Revision: 4153 http://trac.macosforge.org/projects/ruby/changeset/4153 Author: lsansonetti@apple.com Date: 2010-05-25 17:28:19 -0700 (Tue, 25 May 2010) Log Message: ----------- a more efficient class flags mechanism, reduced the number of default slots in RubyObjects to 4, misc fixes Modified Paths: -------------- MacRuby/trunk/class.c MacRuby/trunk/class.h MacRuby/trunk/eval.c MacRuby/trunk/object.c MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/class.c =================================================================== --- MacRuby/trunk/class.c 2010-05-26 00:19:26 UTC (rev 4152) +++ MacRuby/trunk/class.c 2010-05-26 00:28:19 UTC (rev 4153) @@ -42,7 +42,7 @@ rb_obj_imp_allocWithZone(void *rcv, SEL sel, void *zone) { // XXX honor zone? - return (void *)rb_robject_allocate_instance((VALUE)rcv); + return (void *)rb_vm_new_rb_object((VALUE)rcv); } static void * @@ -1253,32 +1253,14 @@ return 0; } -static void *rb_class_flags_key = NULL; +rb_class_flags_cache_t *rb_class_flags; -static unsigned long -rb_class_get_mask(Class k) -{ - return (unsigned long)rb_objc_get_associative_ref(k, &rb_class_flags_key); -} - -static void -rb_class_set_mask(Class k, unsigned long mask) -{ - rb_objc_set_associative_ref(k, &rb_class_flags_key, (void *)mask); -} - -#define RCLASS_MASK_TYPE_SHIFT 16 - -unsigned long -rb_class_get_flags(Class k) -{ - return rb_class_get_mask(k) >> RCLASS_MASK_TYPE_SHIFT; -} - void -rb_class_set_flags(Class k, unsigned long flags) +Init_PreClass(void) { - rb_class_set_mask(k, flags << RCLASS_MASK_TYPE_SHIFT); + rb_class_flags = (rb_class_flags_cache_t *)calloc(CACHE_SIZE, + sizeof(rb_class_flags_cache_t)); + assert(rb_class_flags != NULL); } static int Modified: MacRuby/trunk/class.h =================================================================== --- MacRuby/trunk/class.h 2010-05-26 00:19:26 UTC (rev 4152) +++ MacRuby/trunk/class.h 2010-05-26 00:28:19 UTC (rev 4153) @@ -24,9 +24,75 @@ #define RCLASS_SCOPE_MOD_FUNC (1<<14) /* class opened for module_function methods */ #define RCLASS_KVO_CHECK_DONE (1<<15) /* class created by KVO and flags merged */ -unsigned long rb_class_get_flags(Class k); -void rb_class_set_flags(Class k, unsigned long flags); +typedef struct rb_class_flags_cache { + Class klass; + unsigned long value; + struct rb_class_flags_cache *next; +} rb_class_flags_cache_t; +#define CACHE_SIZE 0x1000 + +extern rb_class_flags_cache_t *rb_class_flags; + +static unsigned int +rb_class_flags_hash(Class k) +{ + return ((unsigned long)k >> 2) & (CACHE_SIZE - 1); +} + +static inline unsigned long +rb_class_get_mask(Class k) +{ + rb_class_flags_cache_t *e = &rb_class_flags[rb_class_flags_hash(k)]; + while (e != NULL) { + if (e->klass == k) { + return e->value; + } + e = e->next; + } + return 0; +} + +static inline void +rb_class_set_mask(Class k, unsigned long mask) +{ + rb_class_flags_cache_t *e = &rb_class_flags[rb_class_flags_hash(k)]; +again: + if (e->klass == k) { +set_value: + e->value = mask; + return; + } + if (e->klass == 0) { + e->klass = k; + goto set_value; + } + if (e->next != NULL) { + e = e->next; + goto again; + } + rb_class_flags_cache_t *ne = (rb_class_flags_cache_t *)malloc( + sizeof(rb_class_flags_cache_t)); + ne->klass = k; + ne->value = mask; + ne->next = NULL; + e->next = ne; +} + +#define RCLASS_MASK_TYPE_SHIFT 16 + +static inline unsigned long +rb_class_get_flags(Class k) +{ + return rb_class_get_mask(k) >> RCLASS_MASK_TYPE_SHIFT; +} + +static inline void +rb_class_set_flags(Class k, unsigned long flags) +{ + rb_class_set_mask(k, flags << RCLASS_MASK_TYPE_SHIFT); +} + #define RCLASS_VERSION(m) (rb_class_get_flags((Class)m)) #define RCLASS_SET_VERSION(m,f) (rb_class_set_flags((Class)m, (unsigned long)f)) #define RCLASS_SET_VERSION_FLAG(m,f) (RCLASS_SET_VERSION((Class)m, (RCLASS_VERSION(m) | f))) Modified: MacRuby/trunk/eval.c =================================================================== --- MacRuby/trunk/eval.c 2010-05-26 00:19:26 UTC (rev 4152) +++ MacRuby/trunk/eval.c 2010-05-26 00:28:19 UTC (rev 4153) @@ -39,6 +39,7 @@ void Init_ext(void); void Init_PreGC(void); void Init_PreVM(void); +void Init_PreClass(void); void Init_PreGCD(void); void Init_PreEncoding(void); @@ -74,6 +75,7 @@ } } + Init_PreClass(); // requires nothing Init_PreGC(); // requires nothing Init_PreVM(); // requires nothing Init_PreGCD(); // requires nothing Modified: MacRuby/trunk/object.c =================================================================== --- MacRuby/trunk/object.c 2010-05-26 00:19:26 UTC (rev 4152) +++ MacRuby/trunk/object.c 2010-05-26 00:28:19 UTC (rev 4153) @@ -362,7 +362,7 @@ return (VALUE)objc_msgSend((id)obj, selCopy); } - VALUE copy = rb_robject_allocate_instance(klass); + VALUE copy = rb_vm_new_rb_object(klass); rb_obj_init_copy(copy, 0, (VALUE)obj); return copy; } @@ -1894,7 +1894,7 @@ if ((RCLASS_VERSION(*(void **)klass) & RCLASS_HAS_ROBJECT_ALLOC) == RCLASS_HAS_ROBJECT_ALLOC) { // Fast path! - return rb_robject_allocate_instance(klass); + return rb_vm_new_rb_object(klass); } return rb_vm_call_with_cache(allocCache, klass, selAlloc, 0, NULL); } Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-05-26 00:19:26 UTC (rev 4152) +++ MacRuby/trunk/vm.cpp 2010-05-26 00:28:19 UTC (rev 4153) @@ -1022,7 +1022,7 @@ sel_getName(sel)); #endif assert(val != NULL); - *(bool *)val = true; + *(unsigned char *)val = 1; } } @@ -1039,8 +1039,8 @@ VALUE included_in_classes = rb_attr_get((VALUE)klass, idIncludedInClasses); if (included_in_classes != Qnil) { - int i, count = RARRAY_LEN(included_in_classes); - for (i = 0; i < count; i++) { + for (int i = 0, count = RARRAY_LEN(included_in_classes); + i < count; i++) { VALUE mod = RARRAY_AT(included_in_classes, i); #if ROXOR_VM_DEBUG printf("forward %c[%s %s] with imp %p node %p types %s\n", @@ -1781,7 +1781,7 @@ if (iter == objc_to_ruby_stubs.end()) { Function *objc_func = RoxorCompiler::shared->compile_objc_stub(func, imp, arity, types); - objc_imp = compile(objc_func, false); + objc_imp = compile(objc_func); objc_to_ruby_stubs[imp] = objc_imp; } else { @@ -4695,8 +4695,8 @@ url = CFBundleCopyResourcesDirectoryURL(bundle); *path = '-'; *(path+1) = 'I'; - assert(CFURLGetFileSystemRepresentation( - url, true, (UInt8 *)&path[2], len - 2)); + assert(CFURLGetFileSystemRepresentation(url, true, (UInt8 *)&path[2], + len - 2)); CFRelease(url); return path; Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2010-05-26 00:19:26 UTC (rev 4152) +++ MacRuby/trunk/vm.h 2010-05-26 00:28:19 UTC (rev 4153) @@ -343,6 +343,8 @@ #define SLOT_CACHE_VIRGIN -2 #define SLOT_CACHE_CANNOT -1 +#define RB_OBJECT_DEFAULT_NUM_SLOTS 4 + typedef struct { struct RBasic basic; rb_object_ivar_slot_t *slots; @@ -386,9 +388,9 @@ } static inline VALUE -rb_robject_allocate_instance(VALUE klass) +rb_vm_new_rb_object(VALUE klass) { - const int num_slots = 10; + const int num_slots = RB_OBJECT_DEFAULT_NUM_SLOTS; rb_object_t *obj = (rb_object_t *)rb_objc_newobj(sizeof(rb_object_t)); GC_WB(&obj->slots, xmalloc(sizeof(rb_object_ivar_slot_t) * num_slots));
participants (1)
-
source_changes@macosforge.org