Commits

Ronald Oussoren committed 8f324b5

- Add a freelist for PyObjCObject, I'm not yet sure if this really helps,
a freelist for PyObjCSelector would probably be more usefull.
- Fix bug in previous patch: we'd sometimes try to free the '-1' methodlist :-(
- Update TODO

  • Participants
  • Parent commits 44cd16c

Comments (0)

Files changed (5)

 - how to integrate with MacPython
 
 
-Platform dependencies in Foundation & AppKit
-............................................
-
-Both modules contain some ugly defines and includes to add platform/version
-specific definitions, like this::
-
-   #ifdef  GNUSTEP
-   #       include "_Fnd_Var.GNUstep.inc"
-   #else /* !GNUSTEP */
-   #if MAC_OS_X_VERSION_10_2 <= MAC_OS_X_VERSION_MAX_ALLOWED
-   #       include "_Fnd_Var.inc"
-   #else
-   #       include "_Fnd_Var.10.1.inc"
-   #endif
-   #endif /* !GNUSTEP */
-
-It would be nice if this could be abstracted away to something like::
-
-   #include PyObjC_PLAT_FILE("_Fnd_Var", ".inc")
-
-Another option would be to make the generator script slightly smarter: have
-it emit #if version guards based on the guards found in the header files.
-
-NOTE: This is mostly solved for MacOSX by running the generator script from
-setup.py, although the mechanism needs to be cleaned up.
-
 Access to method implementations
 ................................
 

pyobjc/Lib/objc/test/test_methodedits.py

 
 import objc
 
-# NSIdEnumerator is not used anywhere else in the unittests
-#MEClass  = objc.runtime.NSIdEnumerator
-
-## If you use this definition this test causes a crash.
 class MEClass(objc.runtime.NSObject):
    pass
 

pyobjc/Modules/objc/class-builder.m

 	new_class->class.METHODLISTS = NULL;
 	new_class->meta_class.METHODLISTS = NULL;
 	GETISA(&new_class->class) = &new_class->meta_class;
-	new_class->class.info = CLS_CLASS;
-	new_class->meta_class.info = CLS_META;
+	new_class->class.info = CLS_CLASS|CLS_METHOD_ARRAY;
+	new_class->meta_class.info = CLS_META|CLS_METHOD_ARRAY;
 
 	new_class->class.name = strdup(name);
 	new_class->meta_class.name = new_class->class.name;
 	 * The code in the objc runtime assumes that the method lists are 
 	 * terminated by '-1', and will happily overwite existing data if
 	 * they aren't.
+	 *
+	 * Ronald filed a bugreport for this: Radar #3317376
 	 */
 	new_class->class.METHODLISTS[0] = (struct objc_method_list*)-1;
 	new_class->meta_class.METHODLISTS[0] = (struct objc_method_list*)-1;

pyobjc/Modules/objc/objc-object.m

 #include <stddef.h>
 #include <objc/Object.h>
 
+
+/*
+ * Basic freelist. 
+ * - to delete an object: obj_freelist[obj_freelist_top++] = OBJ
+ * - to create an object: OBJ = obj_freelist[--obj_freelist_top];
+ */
+#define FREELIST_SIZE 1024
+
+static PyObject* obj_freelist[FREELIST_SIZE];
+static int obj_freelist_top = 0;
+
+
 static NSMapTable* proxy_dict = NULL;
 
 static PyObject* 
 		((PyObjCObject*)obj)->objc_object = nil;
 	}
 
-	obj->ob_type->tp_free(obj);
+	/* Push self onto the freelist */
+	if (obj_freelist_top == FREELIST_SIZE) {
+		obj->ob_type->tp_free(obj);
+	} else {
+		obj_freelist[obj_freelist_top++] = obj;
+	}
 }
 
 
 	PyTypeObject* cls_type;
 	PyObject*     res;
 
-
-
 	res = find_existing_proxy(objc_object);
 	if (res) return res;
 
 		return NULL;
 	}
 
-	res = cls_type->tp_alloc(cls_type, 0);
-	if (res == NULL) {
-		return NULL;
+	if (obj_freelist_top == 0) {
+		res = cls_type->tp_alloc(cls_type, 0);
+		if (res == NULL) {
+			return NULL;
+		}
+	} else {
+		res = obj_freelist[obj_freelist_top-1];
+		obj_freelist_top -= 1;
+		res->ob_refcnt = 1;
+		res->ob_type = cls_type;
 	}
 
 	/* This should be in the tp_alloc for the new class, but 

pyobjc/Modules/objc/objc_support.m

 
 #ifdef GNU_RUNTIME
 
+/* TODO: Move this code to 'gnu-runtime.m' */
+
 # error "GNU_RUNTIME not supported at the moment"
 
 Ivar_t class_getInstanceVariable(Class aClass, const char *name)
 
 struct objc_method_list *objc_allocMethodList(int numMethods)
 {
-  struct objc_method_list *mlist;
+	struct objc_method_list *mlist;
 
-  mlist = malloc(sizeof(struct objc_method_list)
+	mlist = malloc(sizeof(struct objc_method_list)
 		 + ((numMethods+1) * sizeof(struct objc_method)));
 
-  if (mlist == NULL)
-    return NULL;
+	if (mlist == NULL) {
+		return NULL;
+	}
 
-  mlist->method_count = 0;
-  mlist->obsolete = NULL; 
+	mlist->method_count = 0;
+	mlist->obsolete = NULL; 
 
-  return mlist;
+	return mlist;
 }
 
 void objc_freeMethodList(struct objc_method_list **list)
 {
-  if (list)
-    {
-      if (list[0])
-	free(list[0]);
+	struct objc_method_list** cur;
 
-      free(list);
-    }
+	if (list) {
+		cur = list;
+		while (*cur != (struct objc_method_list*) -1) {
+			if (*cur != NULL) {
+				free(*cur);
+			}
+			cur++;
+		}
+		free(list);
+	}
 }
 
 #endif