diff --git a/dtable.c b/dtable.c index ddf736e..60da189 100644 --- a/dtable.c +++ b/dtable.c @@ -653,8 +653,6 @@ PRIVATE void objc_send_initialize(id object) } Class meta = class->isa; - // If this class is already initialized (e.g. in another thread), give up. - if (objc_test_class_flag(class, objc_class_flag_initialized)) { return; } // Make sure that the class is resolved. objc_resolve_class(class); @@ -673,9 +671,17 @@ PRIVATE void objc_send_initialize(id object) if (objc_test_class_flag(class, objc_class_flag_initialized)) { UNLOCK(&initialize_lock); + // We know that initialization has started because the flag is set. + // Check that it's finished by grabbing the class lock. This will be + // released once the class has been fully initialized + objc_sync_enter((id)meta); + objc_sync_exit((id)meta); + assert(dtable_for_class(class) != uninstalled_dtable); return; } + LOCK_OBJECT_FOR_SCOPE((id)meta); + // Set the initialized flag on both this class and its metaclass, to make // sure that +initialize is only ever sent once. objc_set_class_flag(class, objc_class_flag_initialized); @@ -704,7 +710,6 @@ PRIVATE void objc_send_initialize(id object) return; } - LOCK_OBJECT_FOR_SCOPE((id)meta); // Create an entry in the dtable look-aside buffer for this. When sending diff --git a/objc_msgSend.x86-32.S b/objc_msgSend.x86-32.S index 059c219..d0ac7fc 100644 --- a/objc_msgSend.x86-32.S +++ b/objc_msgSend.x86-32.S @@ -4,6 +4,7 @@ #define DATA_OFFSET 12 #define SLOT_OFFSET 16 .macro MSGSEND receiver, sel + .cfi_startproc movl \receiver(%esp), %eax test %eax, %eax # If the receiver is nil jz 4f # return nil @@ -61,14 +62,11 @@ mov \sel(%esp), %ecx lea \receiver(%esp), %eax - push %ebx # Save old %ebx push %ecx # _cmd push %eax # &self - call __i686.get_pc_thunk.bx - addl $_GLOBAL_OFFSET_TABLE_, %ebx + .cfi_def_cfa_offset 12 call slowMsgLookup@PLT - add $8, %esp - popl %ebx + add $8, %esp # restore the stack jmp *%eax @@ -80,6 +78,7 @@ mov (%eax), %eax popl %ebx jmp 1b + .cfi_endproc .endm .globl objc_msgSend .type objc_msgSend, @function