}
+/***********************************************************************
+* 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)
{
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);
// 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);