Revision: 3940 http://trac.macosforge.org/projects/ruby/changeset/3940 Author: lsansonetti@apple.com Date: 2010-04-18 14:11:41 -0700 (Sun, 18 Apr 2010) Log Message: ----------- disable lazy JIT in case the target class already has a custom Objective-C method resolver (CALayer is one) Modified Paths: -------------- MacRuby/trunk/vm.cpp Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-04-17 02:09:53 UTC (rev 3939) +++ MacRuby/trunk/vm.cpp 2010-04-18 21:11:41 UTC (rev 3940) @@ -2092,6 +2092,8 @@ invalidate_respond_to_cache(); } +static bool class_has_custom_resolver(Class klass); + static void prepare_method(Class klass, bool dynamic_class, SEL sel, void *data, const rb_vm_arity_t &arity, int flags, bool precompiled) @@ -2122,6 +2124,7 @@ const char *sel_name = sel_getName(sel); const bool genuine_selector = sel_name[strlen(sel_name) - 1] == ':'; + const bool custom_resolver = class_has_custom_resolver(klass); bool redefined = false; bool added_modfunc = false; SEL orig_sel = sel; @@ -2144,8 +2147,9 @@ } else { Function *func = (Function *)data; - if (m != NULL) { - // The method already exists - we need to JIT it. + if (m != NULL || custom_resolver) { + // The method already exists _or_ the class implemented a custom + // Objective-C method resolver - we need to JIT it. if (imp == NULL) { imp = GET_CORE()->compile(func); } @@ -4881,6 +4885,8 @@ static IMP old_resolveClassMethod_imp = NULL; static IMP old_resolveInstanceMethod_imp = NULL; +static SEL sel_resolveClassMethod = 0; +static SEL sel_resolveInstanceMethod = 0; static BOOL resolveClassMethod_imp(void *self, SEL sel, SEL name) @@ -4900,6 +4906,23 @@ return NO; // TODO call old IMP } +static bool +class_has_custom_resolver(Class klass) +{ + if (!class_isMetaClass(klass)) { + klass = *(Class *)klass; + } + if (class_getMethodImplementation(klass, sel_resolveClassMethod) + != (IMP)resolveClassMethod_imp) { + return true; + } + if (class_getMethodImplementation(klass, sel_resolveInstanceMethod) + != (IMP)resolveInstanceMethod_imp) { + return true; + } + return false; +} + // We can't trust LLVM to pick the right target at runtime. #if __LP64__ # define TARGET_TRIPLE "x86_64-apple-darwin" @@ -4929,16 +4952,16 @@ setup_builtin_stubs(); + Class ns_object = (Class)objc_getClass("NSObject"); Method m; - Class ns_object = (Class)objc_getClass("NSObject"); - m = class_getInstanceMethod(*(Class *)ns_object, - sel_registerName("resolveClassMethod:")); + sel_resolveClassMethod = sel_registerName("resolveClassMethod:"); + m = class_getInstanceMethod(*(Class *)ns_object, sel_resolveClassMethod); assert(m != NULL); old_resolveClassMethod_imp = method_getImplementation(m); method_setImplementation(m, (IMP)resolveClassMethod_imp); - m = class_getInstanceMethod(*(Class *)ns_object, - sel_registerName("resolveInstanceMethod:")); + sel_resolveInstanceMethod = sel_registerName("resolveInstanceMethod:"); + m = class_getInstanceMethod(*(Class *)ns_object, sel_resolveInstanceMethod); assert(m != NULL); old_resolveInstanceMethod_imp = method_getImplementation(m); method_setImplementation(m, (IMP)resolveInstanceMethod_imp);