]> git.saurik.com Git - apple/objc4.git/commitdiff
objc4-371.2.tar.gz mac-os-x-1055 mac-os-x-1056 mac-os-x-1057 mac-os-x-1058 v371.2
authorApple <opensource@apple.com>
Mon, 15 Sep 2008 20:58:36 +0000 (20:58 +0000)
committerApple <opensource@apple.com>
Mon, 15 Sep 2008 20:58:36 +0000 (20:58 +0000)
runtime/objc-layout.m
runtime/objc-private.h
runtime/objc-runtime-old.m

index ed7c03cc4efa50b421dae1c7ed4fc320d04aa2a3..19e3b518d55e28a52f0d169da2a3dd66671f87bc 100644 (file)
@@ -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)
 {
index 65a5559bbbc931b5cb30069cd9b73b2c83355501..3bbfc69358c345f59db504e9d931da9c1e6c82f3 100644 (file)
@@ -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);
index 427dbbe3eb3d61f2f7c6b8b950fa857ab38935ed..946f7f7c940d7aa859f25c5980319db05dec6670 100644 (file)
@@ -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);