Skip to content

Commit 44e60d0

Browse files
edusperoniNathanWalker
authored andcommitted
feat: inline frequently used methods, add caches, thread safety, and use static allocation when possible
1 parent 5c7efc5 commit 44e60d0

File tree

8 files changed

+214
-156
lines changed

8 files changed

+214
-156
lines changed

NativeScript/runtime/Caches.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,6 @@ Caches::~Caches() {
2323
this->PointerInstances.clear();
2424
}
2525

26-
std::shared_ptr<Caches> Caches::Get(Isolate* isolate) {
27-
std::shared_ptr<Caches> cache = perIsolateCaches_->Get(isolate);
28-
if (cache == nullptr) {
29-
cache = std::make_shared<Caches>(isolate);
30-
Caches::perIsolateCaches_->Insert(isolate, cache);
31-
}
32-
33-
return cache;
34-
}
35-
3626
void Caches::Remove(v8::Isolate* isolate) {
3727
Caches::perIsolateCaches_->Remove(isolate);
3828
}

NativeScript/runtime/Caches.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ class Caches {
5252
static std::shared_ptr<ConcurrentMap<std::string, const Meta*>> Metadata;
5353
static std::shared_ptr<ConcurrentMap<int, std::shared_ptr<Caches::WorkerState>>> Workers;
5454

55-
static std::shared_ptr<Caches> Get(v8::Isolate* isolate);
55+
inline static std::shared_ptr<Caches> Get(v8::Isolate* isolate) {
56+
std::shared_ptr<Caches> cache = perIsolateCaches_->Get(isolate);
57+
if (cache == nullptr) {
58+
cache = std::make_shared<Caches>(isolate);
59+
Caches::perIsolateCaches_->Insert(isolate, cache);
60+
}
61+
62+
return cache;
63+
}
5664
static void Remove(v8::Isolate* isolate);
5765

5866
void SetContext(v8::Local<v8::Context> context);

NativeScript/runtime/ConcurrentMap.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ namespace tns {
99
template<class TKey, class TValue>
1010
class ConcurrentMap {
1111
public:
12-
void Insert(TKey& key, TValue value) {
12+
inline void Insert(TKey& key, TValue value) {
1313
std::lock_guard<std::mutex> writerLock(this->containerMutex_);
1414
this->container_[key] = value;
1515
}
1616

17-
TValue Get(TKey& key) {
17+
inline TValue Get(TKey& key) {
1818
bool found;
1919
return this->Get(key, found);
2020
}
2121

22-
TValue Get(TKey& key, bool& found) {
23-
// std::shared_lock<std::shared_timed_mutex> readerLock(this->containerMutex_);
22+
inline TValue Get(TKey& key, bool& found) {
2423
std::lock_guard<std::mutex> writerLock(this->containerMutex_);
2524
auto it = this->container_.find(key);
2625
found = it != this->container_.end();
@@ -30,14 +29,13 @@ class ConcurrentMap {
3029
return nullptr;
3130
}
3231

33-
bool ContainsKey(TKey& key) {
34-
// std::shared_lock<std::shared_timed_mutex> readerLock(this->containerMutex_);
32+
inline bool ContainsKey(TKey& key) {
3533
std::lock_guard<std::mutex> writerLock(this->containerMutex_);
3634
auto it = this->container_.find(key);
3735
return it != this->container_.end();
3836
}
3937

40-
void Remove(TKey& key) {
38+
inline void Remove(TKey& key) {
4139
std::lock_guard<std::mutex> writerLock(this->containerMutex_);
4240
this->container_.erase(key);
4341
}

NativeScript/runtime/FFICall.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ class BaseCall {
2020
~BaseCall() {
2121
}
2222

23-
void* ResultBuffer() {
23+
inline void* ResultBuffer() {
2424
return this->buffer_ + this->returnOffset_;
2525
}
2626

2727
template <typename T>
28-
T& GetResult() {
28+
inline T& GetResult() {
2929
return *static_cast<T*>(this->ResultBuffer());
3030
}
3131
protected:
@@ -72,7 +72,12 @@ class FFICall: public BaseCall {
7272
public:
7373
FFICall(ParametrizedCall* parametrizedCall): BaseCall(nullptr) {
7474
this->returnOffset_ = parametrizedCall->ReturnOffset;
75-
this->buffer_ = reinterpret_cast<uint8_t*>(malloc(parametrizedCall->StackSize));
75+
this->useDynamicBuffer_ = parametrizedCall->StackSize > 512;
76+
if(this->useDynamicBuffer_) {
77+
this->buffer_ = reinterpret_cast<uint8_t*>(malloc(parametrizedCall->StackSize));
78+
} else {
79+
this->buffer_ = reinterpret_cast<uint8_t*>(this->staticBuffer);
80+
}
7681

7782
this->argsArray_ = reinterpret_cast<void**>(this->buffer_);
7883
for (size_t i = 0; i < parametrizedCall->Cif->nargs; i++) {
@@ -81,23 +86,27 @@ class FFICall: public BaseCall {
8186
}
8287

8388
~FFICall() {
84-
free(this->buffer_);
89+
if(this->useDynamicBuffer_) {
90+
free(this->buffer_);
91+
}
8592
}
8693

8794
static ffi_type* GetArgumentType(const TypeEncoding* typeEncoding, bool isStructMember = false);
8895
static StructInfo GetStructInfo(const StructMeta* structMeta, std::string structName = "");
8996
static StructInfo GetStructInfo(size_t fieldsCount, const TypeEncoding* fieldEncoding, const String* fieldNames, std::string structName = "");
9097

91-
void* ArgumentBuffer(unsigned index) {
98+
inline void* ArgumentBuffer(unsigned index) {
9299
return this->argsArray_[index];
93100
}
94101

95-
void** ArgsArray() {
102+
inline void** ArgsArray() {
96103
return this->argsArray_;
97104
}
98105
private:
99106
static robin_hood::unordered_map<std::string, StructInfo> structInfosCache_;
100107
void** argsArray_;
108+
bool useDynamicBuffer_;
109+
uint8_t staticBuffer[512];
101110
};
102111

103112
}

NativeScript/runtime/Helpers.h

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,66 @@ extern "C" void NSLog(CFStringRef format, ...);
1515

1616
namespace tns {
1717

18-
v8::Local<v8::String> ToV8String(v8::Isolate* isolate, std::string value);
19-
std::string ToString(v8::Isolate* isolate, const v8::Local<v8::Value>& value);
18+
inline v8::Local<v8::String> ToV8String(v8::Isolate* isolate, std::string value) {
19+
return v8::String::NewFromUtf8(isolate, value.c_str(), v8::NewStringType::kNormal, (int)value.length()).ToLocalChecked();
20+
}
21+
inline std::string ToString(v8::Isolate* isolate, const v8::Local<v8::Value>& value) {
22+
if (value.IsEmpty()) {
23+
return std::string();
24+
}
25+
26+
if (value->IsStringObject()) {
27+
v8::Local<v8::String> obj = value.As<v8::StringObject>()->ValueOf();
28+
return tns::ToString(isolate, obj);
29+
}
30+
31+
v8::String::Utf8Value result(isolate, value);
32+
33+
const char* val = *result;
34+
if (val == nullptr) {
35+
return std::string();
36+
}
37+
38+
return std::string(*result);
39+
}
2040
std::u16string ToUtf16String(v8::Isolate* isolate, const v8::Local<v8::Value>& value);
21-
double ToNumber(v8::Isolate* isolate, const v8::Local<v8::Value>& value);
22-
bool ToBool(const v8::Local<v8::Value>& value);
41+
inline double ToNumber(v8::Isolate* isolate, const v8::Local<v8::Value>& value) {
42+
double result = NAN;
43+
44+
if (value.IsEmpty()) {
45+
return result;
46+
}
47+
48+
if (value->IsNumberObject()) {
49+
result = value.As<v8::NumberObject>()->ValueOf();
50+
} else if (value->IsNumber()) {
51+
result = value.As<v8::Number>()->Value();
52+
} else {
53+
v8::Local<v8::Number> number;
54+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
55+
bool success = value->ToNumber(context).ToLocal(&number);
56+
if (success) {
57+
result = number->Value();
58+
}
59+
}
60+
61+
return result;
62+
}
63+
inline bool ToBool(const v8::Local<v8::Value>& value) {
64+
bool result = false;
65+
66+
if (value.IsEmpty()) {
67+
return result;
68+
}
69+
70+
if (value->IsBooleanObject()) {
71+
result = value.As<v8::BooleanObject>()->ValueOf();
72+
} else if (value->IsBoolean()) {
73+
result = value.As<v8::Boolean>()->Value();
74+
}
75+
76+
return result;
77+
}
2378
std::vector<uint16_t> ToVector(const std::string& value);
2479

2580
bool Exists(const char* fullPath);

NativeScript/runtime/Helpers.mm

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,6 @@
2222
uint8_t* BinBuffer = new uint8_t[BUFFER_SIZE];
2323
}
2424

25-
Local<String> tns::ToV8String(Isolate* isolate, std::string value) {
26-
return v8::String::NewFromUtf8(isolate, value.c_str(), NewStringType::kNormal, (int)value.length()).ToLocalChecked();
27-
}
28-
29-
std::string tns::ToString(Isolate* isolate, const Local<Value>& value) {
30-
if (value.IsEmpty()) {
31-
return std::string();
32-
}
33-
34-
if (value->IsStringObject()) {
35-
Local<v8::String> obj = value.As<StringObject>()->ValueOf();
36-
return tns::ToString(isolate, obj);
37-
}
38-
39-
v8::String::Utf8Value result(isolate, value);
40-
41-
const char* val = *result;
42-
if (val == nullptr) {
43-
return std::string();
44-
}
45-
46-
return std::string(*result);
47-
}
48-
4925
std::u16string tns::ToUtf16String(Isolate* isolate, const Local<Value>& value) {
5026
std::string valueStr = tns::ToString(isolate, value);
5127
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
@@ -54,45 +30,6 @@
5430
return value16;
5531
}
5632

57-
double tns::ToNumber(Isolate* isolate, const Local<Value>& value) {
58-
double result = NAN;
59-
60-
if (value.IsEmpty()) {
61-
return result;
62-
}
63-
64-
if (value->IsNumberObject()) {
65-
result = value.As<NumberObject>()->ValueOf();
66-
} else if (value->IsNumber()) {
67-
result = value.As<Number>()->Value();
68-
} else {
69-
Local<Number> number;
70-
Local<Context> context = isolate->GetCurrentContext();
71-
bool success = value->ToNumber(context).ToLocal(&number);
72-
if (success) {
73-
result = number->Value();
74-
}
75-
}
76-
77-
return result;
78-
}
79-
80-
bool tns::ToBool(const Local<Value>& value) {
81-
bool result = false;
82-
83-
if (value.IsEmpty()) {
84-
return result;
85-
}
86-
87-
if (value->IsBooleanObject()) {
88-
result = value.As<BooleanObject>()->ValueOf();
89-
} else if (value->IsBoolean()) {
90-
result = value.As<v8::Boolean>()->Value();
91-
}
92-
93-
return result;
94-
}
95-
9633
std::vector<uint16_t> tns::ToVector(const std::string& value) {
9734
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
9835
std::u16string value16 = convert.from_bytes(value);

0 commit comments

Comments
 (0)