Permalink
Browse files

Add Cache for MethodSignature

Caching the MethodSignature when calling Objective-C methods in
Javascript. Make the performance 25% faster than before.
  • Loading branch information...
albert438 committed Aug 19, 2015
1 parent ca14b4b commit 370b8d3b62639de21750f4b9a9668f0abd842591
Showing with 27 additions and 6 deletions.
  1. +26 −5 JSPatch/JPEngine.m
  2. +1 −1 JSPatch/JSPatch.js
View
@@ -8,6 +8,7 @@
#import "JPEngine.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import <UIKit/UIApplication.h>
@interface JPBoxing : NSObject
@property (nonatomic) id obj;
@@ -76,8 +77,8 @@ + (void)startEngine
return defineClass(classDeclaration, instanceMethods, classMethods);
};
context[@"_OC_callI"] = ^id(JSValue *obj, NSString *selectorName, JSValue *arguments, BOOL isSuper) {
return callSelector(nil, selectorName, arguments, obj, isSuper);
context[@"_OC_callI"] = ^id(NSString *className, JSValue *obj, NSString *selectorName, JSValue *arguments, BOOL isSuper) {
return callSelector(className, selectorName, arguments, obj, isSuper);
};
context[@"_OC_callC"] = ^id(NSString *className, NSString *selectorName, JSValue *arguments) {
return callSelector(className, selectorName, arguments, nil, NO);
@@ -170,6 +171,7 @@ + (void)startEngine
_nullObj = [[NSObject alloc] init];
_nilObj = [[NSObject alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
context[@"_OC_null"] = formatOCToJS(_nullObj);
_context = context;
@@ -232,12 +234,19 @@ + (NSMutableDictionary *)registeredStruct
return registeredStruct;
}
+ (void)handleMemoryWarning {
@synchronized(_JSMethodSignatureCache) {
_JSMethodSignatureCache = nil;
}
}
#pragma mark - Implements
static NSMutableDictionary *_JSOverideMethods;
static NSMutableDictionary *_TMPMemoryPool;
static NSRegularExpression *countArgRegex;
static NSMutableDictionary *_propKeys;
static NSMutableDictionary *_JSMethodSignatureCache;
static const void *propKey(NSString *propName) {
if (!_propKeys) _propKeys = [[NSMutableDictionary alloc] init];
@@ -666,7 +675,7 @@ static id callSelector(NSString *className, NSString *selectorName, JSValue *arg
}
}
Class cls = className ? NSClassFromString(className) : [instance class];
Class cls = instance ? [instance class] : NSClassFromString(className);
SEL selector = NSSelectorFromString(selectorName);
if (isSuper) {
@@ -693,8 +702,20 @@ static id callSelector(NSString *className, NSString *selectorName, JSValue *arg
NSInvocation *invocation;
NSMethodSignature *methodSignature;
if (!_JSMethodSignatureCache) {
_JSMethodSignatureCache = [[NSMutableDictionary alloc]init];
}
if (instance) {
methodSignature = [cls instanceMethodSignatureForSelector:selector];
@synchronized(_JSMethodSignatureCache) {
if (!_JSMethodSignatureCache[className]) {
_JSMethodSignatureCache[className] = [[NSMutableDictionary alloc]init];
}
methodSignature = _JSMethodSignatureCache[className][selectorName];
if (!methodSignature) {
methodSignature = [cls instanceMethodSignatureForSelector:selector];
_JSMethodSignatureCache[className][selectorName] = methodSignature;
}
}
NSCAssert(methodSignature, @"unrecognized selector %@ for instance %@", selectorName, instance);
invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:instance];
@@ -1289,4 +1310,4 @@ + (NSDictionary *)getDictOfStruct:(void *)structData structDefine:(NSDictionary
{
return getDictOfStruct(structData, structDefine);
}
@end
@end
View
@@ -61,7 +61,7 @@ var global = this
selectorName += ":"
}
}
var ret = instance ? _OC_callI(instance, selectorName, args, isSuper):
var ret = instance ? _OC_callI(clsName, instance, selectorName, args, isSuper):
_OC_callC(clsName, selectorName, args)
return _formatOCToJS(ret)
}

0 comments on commit 370b8d3

Please sign in to comment.