Skip to content

Commit

Permalink
perf: cache swizzled selector construction (#173)
Browse files Browse the repository at this point in the history
  • Loading branch information
rigor789 authored and NathanWalker committed Jul 22, 2022
1 parent 7a78cca commit de6506b
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ v8
.npmrc

llvm/

# v8 build files...
.gclient_entries
.gclient
.cipd/
2 changes: 1 addition & 1 deletion NativeScript/NativeScript-Prefix.pch
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef NativeScript_Prefix_pch
#define NativeScript_Prefix_pch

#define NATIVESCRIPT_VERSION "8.3.1-alpha.0"
#define NATIVESCRIPT_VERSION "8.3.1-alpha.1"

#ifdef DEBUG
#define SIZEOF_OFF_T 8
Expand Down
20 changes: 15 additions & 5 deletions NativeScript/runtime/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,21 @@ BaseDataWrapper* GetValue(v8::Isolate* isolate, const v8::Local<v8::Value>& val)
void DeleteValue(v8::Isolate* isolate, const v8::Local<v8::Value>& val);
std::vector<v8::Local<v8::Value>> ArgsToVector(const v8::FunctionCallbackInfo<v8::Value>& info);

bool IsString(v8::Local<v8::Value> value);
bool IsNumber(v8::Local<v8::Value> value);
bool IsBool(v8::Local<v8::Value> value);
bool IsArrayOrArrayLike(v8::Isolate* isolate, v8::Local<v8::Value> value);
void* TryGetBufferFromArrayBuffer(v8::Local<v8::Value> value, bool& isArrayBuffer);
inline bool IsString(const v8::Local<v8::Value>& value) {
return !value.IsEmpty() && (value->IsString() || value->IsStringObject());
}

inline bool IsNumber(const v8::Local<v8::Value>& value) {
return !value.IsEmpty() && (value->IsNumber() || value->IsNumberObject());
}

inline bool IsBool(const v8::Local<v8::Value>& value) {
return !value.IsEmpty() && (value->IsBoolean() || value->IsBooleanObject());
}


bool IsArrayOrArrayLike(v8::Isolate* isolate, const v8::Local<v8::Value>& value);
void* TryGetBufferFromArrayBuffer(const v8::Local<v8::Value>& value, bool& isArrayBuffer);

void ExecuteOnMainThread(std::function<void ()> func, bool async = true);

Expand Down
16 changes: 2 additions & 14 deletions NativeScript/runtime/Helpers.mm
Original file line number Diff line number Diff line change
Expand Up @@ -337,19 +337,7 @@
return args;
}

bool tns::IsString(Local<Value> value) {
return !value.IsEmpty() && (value->IsString() || value->IsStringObject());
}

bool tns::IsNumber(Local<Value> value) {
return !value.IsEmpty() && (value->IsNumber() || value->IsNumberObject());
}

bool tns::IsBool(Local<Value> value) {
return !value.IsEmpty() && (value->IsBoolean() || value->IsBooleanObject());
}

bool tns::IsArrayOrArrayLike(Isolate* isolate, Local<Value> value) {
bool tns::IsArrayOrArrayLike(Isolate* isolate, const Local<Value>& value) {
if (value->IsArray()) {
return true;
}
Expand All @@ -365,7 +353,7 @@
return obj->Has(context, ToV8String(isolate, "length")).FromMaybe(false);
}

void* tns::TryGetBufferFromArrayBuffer(v8::Local<v8::Value> value, bool& isArrayBuffer) {
void* tns::TryGetBufferFromArrayBuffer(const v8::Local<v8::Value>& value, bool& isArrayBuffer) {
isArrayBuffer = false;

if (value.IsEmpty() || (!value->IsArrayBuffer() && !value->IsArrayBufferView())) {
Expand Down
2 changes: 2 additions & 0 deletions NativeScript/runtime/Interop.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class Interop {
static bool IsNumbericType(BinaryTypeEncodingType type);
static v8::Local<v8::Object> GetInteropType(v8::Local<v8::Context> context, BinaryTypeEncodingType type);
static std::vector<std::string> GetAdditionalProtocols(const TypeEncoding* typeEncoding);
static SEL GetSwizzledMethodSelector(SEL selector);

template <typename T>
static inline void SetValue(void* dest, T value) {
Expand Down Expand Up @@ -192,6 +193,7 @@ class Interop {

static JSBlockDescriptor kJSBlockDescriptor;
} JSBlock;

};

}
Expand Down
25 changes: 22 additions & 3 deletions NativeScript/runtime/Interop.mm
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "SymbolIterator.h"
#include "UnmanagedType.h"
#include "OneByteStringResource.h"
#include "robin_hood.h"

using namespace v8;

Expand Down Expand Up @@ -1366,6 +1367,26 @@
return result.As<v8::Array>();
}

SEL Interop::GetSwizzledMethodSelector(SEL selector) {
static robin_hood::unordered_map<SEL, SEL> *swizzledMethodSelectorCache = new robin_hood::unordered_map<SEL, SEL>();

SEL swizzledMethodSelector = NULL;

try {
swizzledMethodSelector = swizzledMethodSelectorCache->at(selector);
} catch(const std::out_of_range&) {
// ignore...
}

if(!swizzledMethodSelector) {
swizzledMethodSelector = sel_registerName((Constants::SwizzledPrefix + std::string(sel_getName(selector))).c_str());
// save to cache
swizzledMethodSelectorCache->emplace(selector, swizzledMethodSelector);
}

return swizzledMethodSelector;
}

Local<Value> Interop::CallFunctionInternal(MethodCall& methodCall) {
int initialParameterIndex = methodCall.isPrimitiveFunction_ ? 0 : 2;

Expand Down Expand Up @@ -1401,9 +1422,7 @@

SEL selector = methodCall.selector_;
if (isInstanceMethod) {
NSString* selectorStr = NSStringFromSelector(selector);
NSString* swizzledMethodSelectorStr = [NSString stringWithFormat:@"%s%@", Constants::SwizzledPrefix.c_str(), selectorStr];
SEL swizzledMethodSelector = NSSelectorFromString(swizzledMethodSelectorStr);
SEL swizzledMethodSelector = Interop::GetSwizzledMethodSelector(selector);
if ([methodCall.target_ respondsToSelector:swizzledMethodSelector]) {
selector = swizzledMethodSelector;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@nativescript/ios",
"description": "NativeScript Runtime for iOS",
"version": "8.3.1-alpha.0",
"version": "8.3.1-alpha.1",
"keywords": [
"NativeScript",
"iOS",
Expand Down

0 comments on commit de6506b

Please sign in to comment.