Index: src/runtime/class.m ================================================================== --- src/runtime/class.m +++ src/runtime/class.m @@ -97,21 +97,23 @@ void objc_update_dtable(Class cls) { struct objc_method_list *ml; struct objc_category **cats; - struct objc_sparsearray *dtable; unsigned int i; - if (cls->superclass != Nil) - dtable = objc_sparsearray_copy(cls->superclass->dtable); - else - dtable = objc_sparsearray_new(); + if (cls->dtable == NULL) { + if (cls->superclass != Nil) + cls->dtable = + objc_sparsearray_copy(cls->superclass->dtable); + else + cls->dtable = objc_sparsearray_new(); + } for (ml = cls->methodlist; ml != NULL; ml = ml->next) for (i = 0; i < ml->count; i++) - objc_sparsearray_set(dtable, + objc_sparsearray_set(cls->dtable, (uint32_t)ml->methods[i].sel.uid, ml->methods[i].imp); if ((cats = objc_categories_for_class(cls)) != NULL) { for (i = 0; cats[i] != NULL; i++) { @@ -120,21 +122,16 @@ ml = (cls->info & OBJC_CLASS_INFO_CLASS ? cats[i]->instance_methods : cats[i]->class_methods); for (; ml != NULL; ml = ml->next) for (j = 0; j < ml->count; j++) - objc_sparsearray_set(dtable, + objc_sparsearray_set(cls->dtable, (uint32_t)ml->methods[j].sel.uid, ml->methods[j].imp); } } - if (cls->dtable != NULL) - objc_sparsearray_free_when_singlethreaded(cls->dtable); - - cls->dtable = dtable; - if (cls->subclass_list != NULL) for (i = 0; cls->subclass_list[i] != NULL; i++) objc_update_dtable(cls->subclass_list[i]); } Index: src/runtime/sparsearray.m ================================================================== --- src/runtime/sparsearray.m +++ src/runtime/sparsearray.m @@ -158,30 +158,10 @@ } free(s); } -void -objc_sparsearray_free_when_singlethreaded(struct objc_sparsearray *s) -{ - size_t i, j; - - for (i = 0; i < 256; i++) { - if (s->buckets[i]->empty) - continue; - - for (j = 0; j < 256; j++) - if (!s->buckets[i]->buckets[j]->empty) - objc_free_when_singlethreaded( - s->buckets[i]->buckets[j]); - - objc_free_when_singlethreaded(s->buckets[i]); - } - - objc_free_when_singlethreaded(s); -} - void objc_sparsearray_cleanup(void) { if (empty_level2 != NULL) free(empty_level2); Index: src/runtime/threading.m ================================================================== --- src/runtime/threading.m +++ src/runtime/threading.m @@ -21,13 +21,10 @@ #import "runtime.h" #import "runtime-private.h" static objc_mutex_t global_mutex; -static int num_threads = 1; -static void **free_queue = NULL; -static size_t free_queue_cnt = 0; BOOL objc_mutex_new(objc_mutex_t *mutex) { if (!of_mutex_new(&mutex->mutex )) @@ -95,58 +92,5 @@ objc_global_mutex_free(void) { if (!objc_mutex_free(&global_mutex)) ERROR("Failed to free global mutex!"); } - -void -objc_thread_add(void) -{ - /* - * If some class is being initialized, we want to wait for it, thus - * we use the global lock instead of atomic operations. - */ - objc_global_mutex_lock(); - num_threads++; - objc_global_mutex_unlock(); -} - -void -objc_thread_remove(void) -{ - size_t i; - - objc_global_mutex_lock(); - - if (free_queue != NULL) { - for (i = 0; i < free_queue_cnt; i++) - free(free_queue[i]); - - free(free_queue); - - free_queue = NULL; - free_queue_cnt = 0; - } - - num_threads--; - objc_global_mutex_unlock(); -} - -void -objc_free_when_singlethreaded(void *ptr) -{ - if (num_threads == 1) { - free(ptr); - return; - } - - if (free_queue == NULL) - free_queue = malloc(sizeof(void*)); - else - free_queue = realloc(free_queue, sizeof(void*) * - (free_queue_cnt + 1)); - - if (free_queue == NULL) - ERROR("Not enough memory for queue of pointers to free!"); - - free_queue[free_queue_cnt++] = ptr; -}