Comment: | New autorelease pools.
This uses the runtime's autorelease pools and implements autorelease These new pools should be ARC-compatible now and finally, it should be As a bonus, it's significantly faster to use the ObjFW runtime with |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
f5927f8a8401bbcbf704764a1e150745 |
User & Date: | js on 2012-07-14 20:00:11 |
Other Links: | manifest | tags |
2012-07-14
| ||
20:38 | Let of_tlskey_* use void* instead of id. check-in: e379516a39 user: js tags: trunk | |
20:00 | New autorelease pools. check-in: f5927f8a84 user: js tags: trunk | |
09:59 | objfw-compile: Always add -Wall. check-in: 7e95e4a343 user: js tags: trunk | |
Modified src/OFAutoreleasePool.h from [ed23b75b52] to [d6d789a7b7].
︙ | ︙ | |||
22 23 24 25 26 27 28 | * The OFAutoreleasePool class is a class that keeps track of objects that will * be released when the autorelease pool is released. * * Every thread has its own stack of autorelease pools. */ @interface OFAutoreleasePool: OFObject { | < | < > > | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | * The OFAutoreleasePool class is a class that keeps track of objects that will * be released when the autorelease pool is released. * * Every thread has its own stack of autorelease pools. */ @interface OFAutoreleasePool: OFObject { void *pool; BOOL ignoreRelease; } /** * \brief Adds an object to the autorelease pool at the top of the * thread-specific autorelease pool stack. * * \param object The object to add to the autorelease pool * \return The object */ + (id)addObject: (id)object; + (void)_releaseAll; /** * \brief Releases all objects in the autorelease pool. * * This does not free the memory allocated to store pointers to the objects in * the pool, so reusing the pool does not allocate any memory until the previous * number of objects is exceeded. It behaves this way to optimize loops that |
︙ | ︙ |
Modified src/OFAutoreleasePool.m from [6d60b227fa] to [9b9e08d0f0].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #include "config.h" #include <stdlib.h> #import "OFAutoreleasePool.h" #import "OFArray.h" | < < < < < < < | < | | < < | < < | < < < | < | | < < < | < < | < < < | | < < < < < < < < < < < < < < < < < < < < | < < < < | < < < < < < < | < < < < < < < | < | | < < < < < < | < < < < < < | < < | | | | < | < < < | < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < | | | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include "config.h" #include <stdlib.h> #import "OFAutoreleasePool.h" #import "OFArray.h" #import "OFNotImplementedException.h" extern id _objc_rootAutorelease(id); extern void* objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void*); static __thread void *first = NULL; @implementation OFAutoreleasePool + (id)addObject: (id)object { if (first == NULL) [[OFAutoreleasePool alloc] init]; return _objc_rootAutorelease(object); } + (void)_releaseAll { objc_autoreleasePoolPop(first); } - init { self = [super init]; @try { pool = objc_autoreleasePoolPush(); if (first == NULL) first = pool; _objc_rootAutorelease(self); } @catch (id e) { [self release]; @throw e; } return self; } - (void)releaseObjects { ignoreRelease = YES; objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); _objc_rootAutorelease(self); ignoreRelease = NO; } - (void)release { [self dealloc]; } - (void)drain { [self dealloc]; } - (void)dealloc { if (ignoreRelease) return; ignoreRelease = YES; if (first == pool) first = NULL; objc_autoreleasePoolPop(pool); [super dealloc]; } - retain { @throw [OFNotImplementedException exceptionWithClass: [self class] |
︙ | ︙ |
Modified src/OFObject.m from [470fa11181] to [d5e3e3b36f].
︙ | ︙ | |||
767 768 769 770 771 772 773 | /* * Cache OFAutoreleasePool since class lookups are expensive with the * GNU ABI. */ if (autoreleasePool == Nil) autoreleasePool = [OFAutoreleasePool class]; | | < < | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | /* * Cache OFAutoreleasePool since class lookups are expensive with the * GNU ABI. */ if (autoreleasePool == Nil) autoreleasePool = [OFAutoreleasePool class]; return [autoreleasePool addObject: self]; } - self { return self; } |
︙ | ︙ |
Modified src/runtime/Makefile from [756512ba6a] to [a09545f782].
1 2 3 4 5 | include ../../extra.mk STATIC_PIC_LIB_NOINST = ${RUNTIME_LIB_A} STATIC_LIB_NOINST = ${RUNTIME_A} | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | include ../../extra.mk STATIC_PIC_LIB_NOINST = ${RUNTIME_LIB_A} STATIC_LIB_NOINST = ${RUNTIME_A} SRCS = autorelease.m \ category.m \ class.m \ exception.m \ hashtable.m \ init.m \ lookup.m \ ${LOOKUP_S} \ property.m \ |
︙ | ︙ |
Added src/runtime/autorelease.m version [aef7e3462c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012 * Jonathan Schleifer <js@webkeks.org> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #import "runtime.h" #import "runtime-private.h" #import "OFObject.h" #import "macros.h" static __thread id *objects = NULL; static __thread id *top = NULL; static size_t size = 0; id objc_autorelease(id object) { return [object autorelease]; } void* objc_autoreleasePoolPush() { ptrdiff_t offset = top - objects; return (void*)offset; } void objc_autoreleasePoolPop(void *offset) { id *pool = objects + (ptrdiff_t)offset; id *iter; for (iter = pool; iter < top; iter++) [*iter release]; top = pool; } id _objc_rootAutorelease(id object) { if (objects == NULL) { if ((objects = malloc(of_pagesize)) == NULL) ERROR("Out of memory for autorelease pools!") top = objects; } if ((uintptr_t)top >= (uintptr_t)objects + size) { ptrdiff_t diff = top - objects; size += of_pagesize; if ((objects = realloc(objects, size)) == NULL) ERROR("Out of memory for autorelease pools!") top = objects + diff; } *top = object; top++; return object; } |
Modified src/runtime/runtime.h from [dd41eb5b33] to [10b66bd071].
︙ | ︙ | |||
128 129 130 131 132 133 134 135 136 137 138 139 140 141 | extern BOOL protocol_isEqual(Protocol*, Protocol*); extern BOOL protocol_conformsToProtocol(Protocol*, Protocol*); extern void objc_thread_add(void); extern void objc_thread_remove(void); extern void objc_exit(void); extern objc_uncaught_exception_handler objc_setUncaughtExceptionHandler( objc_uncaught_exception_handler); static inline Class object_getClass(id obj_) { struct objc_object *obj = (struct objc_object*)obj_; return obj->isa; | > > > > | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | extern BOOL protocol_isEqual(Protocol*, Protocol*); extern BOOL protocol_conformsToProtocol(Protocol*, Protocol*); extern void objc_thread_add(void); extern void objc_thread_remove(void); extern void objc_exit(void); extern objc_uncaught_exception_handler objc_setUncaughtExceptionHandler( objc_uncaught_exception_handler); extern id objc_autorelease(id); extern void* objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void*); extern id _objc_rootAutorelease(id); static inline Class object_getClass(id obj_) { struct objc_object *obj = (struct objc_object*)obj_; return obj->isa; |
︙ | ︙ |