]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/Accessors.subproj/objc-accessors.m
objc4-437.tar.gz
[apple/objc4.git] / runtime / Accessors.subproj / objc-accessors.m
index 3add7d297cd558238fee505725f043412f6d6c18..d1e5617d8b3ed55f1d32e65f8af75c3ab914dc26 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2007 Apple Inc.  All Rights Reserved.
+ * Copyright (c) 2006-2008 Apple Inc.  All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 #import <libkern/OSAtomic.h>
 
+#import "objc-private.h"
+#import "objc-auto.h"
+#import "runtime.h"
 #import "objc-accessors.h"
-#import <objc/objc-auto.h>
-#import <objc/runtime.h>
-#import "../objc-private.h"
-
-#import "/usr/local/include/auto_zone.h"
-
-#import "objc-accessors-table.h"
 
 // stub interface declarations to make compiler happy.
 
 - (id)copyWithZone:(void *)zone;
 @end
 
+@interface __NSMutableCopyable
+- (id)mutableCopyWithZone:(void *)zone;
+@end
+
 @interface __NSRetained
 - (id)retain;
 - (oneway void)release;
 - (id)autorelease;
 @end
 
-static /*inline*/ IMP optimized_getter_for_gc(id self, SEL name, ptrdiff_t offset) {
-    // replace this method with a faster version that does no message sends, and fewer tests.
-    IMP getter = GETPROPERTY_IMP(offset);
-    if (getter != NULL) {
-        // HACK ALERT:  replaces the IMP in the cache!
-        Class cls = self->isa;
-        Method method = class_getInstanceMethod(cls, name);
-        if (method_getImplementation(method) != getter)
-            method_setImplementation(method, getter);
-    }
-    return getter;
-}
-
-static /*inline*/ IMP optimized_setter_for_gc(id self, SEL name, ptrdiff_t offset) {
-    // replace this method with a faster version that does no message sends.
-    IMP setter = SETPROPERTY_IMP(offset);
-    if (setter != NULL) {
-        // HACK ALERT:  replaces the IMP in the cache!
-        Class cls = self->isa;
-        Method method = class_getInstanceMethod(cls, name);
-        if (method_getImplementation(method) != setter)
-            method_setImplementation(method, setter);
-    }
-    return setter;
-}
-
-// ATOMIC entry points
 
 typedef uintptr_t spin_lock_t;
 extern void _spin_lock(spin_lock_t *lockp);
@@ -89,11 +62,6 @@ static spin_lock_t PropertyLocks[1 << GOODPOWER] = { 0 };
 
 id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
     if (UseGC) {
-        // FIXME:  we could optimize getters when a class is first initialized, then KVO won't get confused.
-        if (false) {
-            IMP getter = optimized_getter_for_gc(self, _cmd, offset);
-            if (getter) return getter(self, _cmd);
-        }
         return *(id*) ((char*)self + offset);
     }
     
@@ -111,18 +79,12 @@ id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
     return [value autorelease];
 }
 
+enum { OBJC_PROPERTY_RETAIN = 0, OBJC_PROPERTY_COPY = 1, OBJC_PROPERTY_MUTABLECOPY = 2 };
 
 void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL atomic, BOOL shouldCopy) {
     if (UseGC) {
         if (shouldCopy) {
-            newValue = [newValue copyWithZone:NULL];
-        }
-        else if (false) {
-            IMP setter = optimized_setter_for_gc(self, _cmd, offset);
-            if (setter) {
-                setter(self, _cmd, newValue);
-                return;
-            }
+            newValue = (shouldCopy == OBJC_PROPERTY_MUTABLECOPY ? [newValue mutableCopyWithZone:NULL] : [newValue copyWithZone:NULL]);
         }
         objc_assign_ivar_internal(newValue, self, offset);
         return;
@@ -134,7 +96,11 @@ void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL ato
     // atomic or not, if slot would be unchanged, do nothing.
     if (!shouldCopy && *slot == newValue) return;
    
-    newValue = (shouldCopy ? [newValue copyWithZone:NULL] : [newValue retain]);
+    if (shouldCopy) {
+        newValue = (shouldCopy == OBJC_PROPERTY_MUTABLECOPY ? [newValue mutableCopyWithZone:NULL] : [newValue copyWithZone:NULL]);
+    } else {
+        newValue = [newValue retain];
+    }
 
     if (!atomic) {
         oldValue = *slot;
@@ -151,8 +117,6 @@ void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL ato
 }
 
 
-__private_extern__ auto_zone_t *gc_zone;
-
 // This entry point was designed wrong.  When used as a getter, src needs to be locked so that
 // if simultaneously used for a setter then there would be contention on src.
 // So we need two locks - one of which will be contended.
@@ -187,45 +151,3 @@ void objc_copyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic, B
     }
 }
 
-// PRE-ATOMIC entry points
-
-id <NSCopying> object_getProperty_bycopy(id self, SEL _cmd, ptrdiff_t offset) {
-    if (UseGC) {
-        IMP getter = optimized_getter_for_gc(self, _cmd, offset);
-        if (getter) return getter(self, _cmd);
-    }
-    id *slot = (id*) ((char*)self + offset);
-    return *slot;
-}
-
-void object_setProperty_bycopy(id self, SEL _cmd, id <NSCopying> value, ptrdiff_t offset) {
-    id *slot = (id*) ((char*)self + offset);
-    id oldValue = *slot;
-    objc_assign_ivar_internal([value copyWithZone:NULL], self, offset);
-    [oldValue release];
-}
-
-id object_getProperty_byref(id self, SEL _cmd, ptrdiff_t offset) {
-    if (UseGC) {
-        IMP getter = optimized_getter_for_gc(self, _cmd, offset);
-        if (getter) return getter(self, _cmd);
-    }
-    id *slot = (id*) ((char*)self + offset);
-    return *slot;
-}
-
-void object_setProperty_byref(id self, SEL _cmd, id value, ptrdiff_t offset) {
-    if (UseGC) {
-        IMP setter = optimized_setter_for_gc(self, _cmd, offset);
-        if (setter) {
-            setter(self, _cmd, value);
-            return;
-        }
-    }
-    id *slot = (id*) ((char*)self + offset);
-    id oldValue = *slot;
-    if (oldValue != value) {
-        objc_assign_ivar_internal([value retain], self, offset);
-        [oldValue release];
-    }
-}