From 49510430221eeb9edf7d4005308350d71d4af53a Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Mon, 23 Mar 2015 14:08:40 +0000 Subject: [PATCH 1/4] Add .gitignore. --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff7c15 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*~ +.*.sw? +Build +Debug +Release From 71c1437ac27d6df7f57b31974efb6fe46ac8a16e Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Mon, 23 Mar 2015 14:09:15 +0000 Subject: [PATCH 2/4] If we find LLVM, but fail to find the relevant cmake modules, give a helpful error and then continue without building the optimisations, instead of just dying. --- opts/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/opts/CMakeLists.txt b/opts/CMakeLists.txt index aa3f794..5140443 100644 --- a/opts/CMakeLists.txt +++ b/opts/CMakeLists.txt @@ -1,7 +1,12 @@ cmake_minimum_required(VERSION 2.8) find_package(LLVM) -include(AddLLVM) +include(AddLLVM OPTIONAL RESULT_VARIABLE INCLUDED_LLVM) + +if (${INCLUDED_LLVM} STREQUAL "NOTFOUND") + message(WARNING "Failed to include AddLLVM CMake module") +else() +message("Included: '${INCLUDED_LLVM}'") add_definitions(${LLVM_DEFINITIONS}) include_directories(${LLVM_INCLUDE_DIRS}) @@ -39,3 +44,4 @@ string(REGEX REPLACE "([0-9]*).([0-9]*).*" "-DLLVM_MAJOR=\\1 -DLLVM_MINOR=\\2" L set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_VERSION} -fno-rtti") include_directories( ${LLVM_INCLUDE_DIRS} "${LLVM_SRC}/include/" "${LLVM_OBJ}/include/") +endif() # AddLLVM include failed From d6ca506d6ad08948a6cdf87d1bde4169c7b65bcc Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Mon, 23 Mar 2015 14:10:07 +0000 Subject: [PATCH 3/4] Make sure that we remove hidden classes from the subclass list, as well as adding them. Also make sure that subclass list manipulation is protected by the runtime lock. --- associate.m | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/associate.m b/associate.m index 0343363..3db8495 100644 --- a/associate.m +++ b/associate.m @@ -214,6 +214,7 @@ static Class allocateHiddenClass(Class superclass) newClass->dtable = uninstalled_dtable; newClass->instance_size = superclass->instance_size; + LOCK_RUNTIME_FOR_SCOPE(); newClass->sibling_class = superclass->subclass_list; superclass->subclass_list = newClass; @@ -238,14 +239,36 @@ static inline Class initHiddenClassForObject(id obj) static void deallocHiddenClass(id obj, SEL _cmd) { + LOCK_RUNTIME_FOR_SCOPE(); Class hiddenClass = findHiddenClass(obj); // After calling [super dealloc], the object will no longer exist. - // Free the hidden + // Free the hidden class. struct reference_list *list = object_getIndexedIvars(hiddenClass); DESTROY_LOCK(&list->lock); cleanupReferenceList(list); freeReferenceList(list->next); + fprintf(stderr, "Deallocating dtable %p\n", hiddenClass->dtable); free_dtable(hiddenClass->dtable); + // We shouldn't have any subclasses left at this point + assert(hiddenClass->subclass_list == 0); + // Remove the class from the subclass list of its superclass + Class sub = hiddenClass->super_class->subclass_list; + if (sub == hiddenClass) + { + hiddenClass->super_class->subclass_list = hiddenClass->sibling_class; + } + else + { + while (sub != NULL) + { + if ((Class)sub->sibling_class == hiddenClass) + { + sub->sibling_class = hiddenClass->sibling_class; + break; + } + sub = sub->sibling_class; + } + } // Free the class free(hiddenClass); } From a74542ae4f264b199704d5291784effc3d0a25bd Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Mon, 23 Mar 2015 14:10:43 +0000 Subject: [PATCH 4/4] =?UTF-8?q?Add=20a=20test=20that=20hidden=20classes=20?= =?UTF-8?q?are=20correctly=20deallocated=20and=20don=E2=80=99t=20leave=20t?= =?UTF-8?q?he=20runtime=20in=20an=20undefined=20state.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Test/AssociatedObject2.m | 37 +++++++++++++++++++++++++++++++++++++ Test/CMakeLists.txt | 1 + Test/Test.h | 6 ++++++ 3 files changed, 44 insertions(+) create mode 100644 Test/AssociatedObject2.m diff --git a/Test/AssociatedObject2.m b/Test/AssociatedObject2.m new file mode 100644 index 0000000..e8f7d53 --- /dev/null +++ b/Test/AssociatedObject2.m @@ -0,0 +1,37 @@ +#include "Test.h" + +@interface MLTestClass : Test { +@public +} +- (void)someF; +@end + +@implementation MLTestClass +- (void)someF +{ +} + +@end + +static void ff(id obj, SEL _cmd) +{ +} + + +int main() +{ + static char static_char; + MLTestClass * tc; + tc = [MLTestClass new]; + objc_setAssociatedObject(tc, &static_char, (id)1223, OBJC_ASSOCIATION_ASSIGN); + [tc release]; + int i = 0; + tc = [MLTestClass new]; + objc_setAssociatedObject(tc, &static_char, (id)1223, OBJC_ASSOCIATION_ASSIGN); + SEL some_sel = sel_registerName(".some_sel"); + const char *types = "v@:"; + class_addMethod(object_getClass(tc), some_sel, + (IMP)ff, types); + int j = (int)objc_getAssociatedObject(tc, &static_char); + [tc release]; +} diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index e8db645..8e253ae 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -8,6 +8,7 @@ set(TESTS #alignTest.m AllocatePair.m AssociatedObject.m + AssociatedObject2.m BlockImpTest.m BlockTest_arc.m BoxedForeignException.m diff --git a/Test/Test.h b/Test/Test.h index d61d90b..6ca0261 100644 --- a/Test/Test.h +++ b/Test/Test.h @@ -15,6 +15,12 @@ __attribute__((objc_root_class)) @interface Test { id isa; } + (Class)class; + (id)new; +#if !__has_feature(objc_arc) +- (void)dealloc; +- (id)autorelease; +- (id)retain; +- (void)release; +#endif @end #if !__has_feature(objc_arc)