From: Apple Date: Mon, 15 Sep 2008 20:58:36 +0000 (+0000) Subject: objc4-371.2.tar.gz X-Git-Tag: mac-os-x-1055^0 X-Git-Url: https://git.saurik.com/apple/objc4.git/commitdiff_plain/7c0e6487d7b67b6bf6c632300ee4b74e8950b051 objc4-371.2.tar.gz --- diff --git a/runtime/objc-layout.m b/runtime/objc-layout.m index ed7c03c..19e3b51 100644 --- a/runtime/objc-layout.m +++ b/runtime/objc-layout.m @@ -278,6 +278,36 @@ layout_string_create(layout_bitmap bits) } +/*********************************************************************** +* layout_bitmap_or +* Set dst=dst|src. +* dst must be at least as long as src. +* Returns YES if any of dst's bits were changed. +**********************************************************************/ +__private_extern__ BOOL +layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg) +{ + if (dst.bitCount < src.bitCount) { + _objc_fatal("layout bitmap too short%s%s", msg ? ": " : "", msg ?: ""); + } + + BOOL changed = NO; + + // fixme optimize for byte/word at a time + size_t bit; + for (bit = 0; bit < src.bitCount; bit++) { + int dstset = dst.bits[bit/8] & (1 << (bit % 8)); + int srcset = src.bits[bit/8] & (1 << (bit % 8)); + if (srcset && !dstset) { + changed = YES; + dst.bits[bit/8] |= 1 << (bit % 8); + } + } + + return changed; +} + + __private_extern__ void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset) { diff --git a/runtime/objc-private.h b/runtime/objc-private.h index 65a5559..3bbfc69 100644 --- a/runtime/objc-private.h +++ b/runtime/objc-private.h @@ -576,6 +576,8 @@ extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount); extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos); extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src, size_t oldSrcInstanceSize); +extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg); + // fixme runtime extern id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler); diff --git a/runtime/objc-runtime-old.m b/runtime/objc-runtime-old.m index 427dbbe..946f7f7 100644 --- a/runtime/objc-runtime-old.m +++ b/runtime/objc-runtime-old.m @@ -872,6 +872,39 @@ static void really_connect_class(struct old_class *cls, // Connect superclass pointers. set_superclass(cls, supercls); + // Update GC layouts + // For paranoia, this is a conservative update: only non-strong -> strong + // is corrected. Any bugs will be leaks instead of crashes. + // rdar://5791689 covers any less-paranoid more-complete fix. + if (UseGC && supercls && + (cls->info & CLS_EXT) && (supercls->info & CLS_EXT)) + { + BOOL layoutsChanged = NO; + layout_bitmap ivarBitmap = + layout_bitmap_create(cls->ivar_layout, + cls->instance_size, + cls->instance_size, NO); + + layout_bitmap superBitmap = + layout_bitmap_create(supercls->ivar_layout, + supercls->instance_size, + supercls->instance_size, NO); + layoutsChanged |= layout_bitmap_or(ivarBitmap, superBitmap, cls->name); + layout_bitmap_free(superBitmap); + + if (layoutsChanged) { + // Rebuild layout strings. + if (PrintIvars) { + _objc_inform("IVARS: gc layout changed for class %s (super %s)", + cls->name, supercls->name); + } + cls->ivar_layout = layout_string_create(ivarBitmap); + } + + layout_bitmap_free(ivarBitmap); + } + + // Done! cls->info |= CLS_CONNECTED; OBJC_LOCK(&classLock);