Overview
Comment: | Add support for 16 bit selector UIDs. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | runtime |
Files: | files | file ages | folders |
SHA3-256: |
fef47937e59adeeb6f868fa89ac3ecdd |
User & Date: | js on 2012-05-08 20:30:58 |
Other Links: | branch diff | manifest | tags |
Context
2012-05-09
| ||
13:54 | Better way of calling the forwarding handler. check-in: f5747ff94a user: js tags: runtime | |
2012-05-08
| ||
20:30 | Add support for 16 bit selector UIDs. check-in: fef47937e5 user: js tags: runtime | |
2012-05-07
| ||
08:24 | Abort when all selector slots are exhausted. check-in: 1315dd59d4 user: js tags: runtime | |
Changes
Modified configure.ac from [87a986c8ea] to [a12f19a3e6].
︙ | ︙ | |||
146 147 148 149 150 151 152 153 154 155 156 157 158 159 | ]) objc_runtime="ObjFW runtime" AC_CHECK_HEADER(objc/objc.h) AC_MSG_CHECKING(which Objective C runtime to use) AC_ARG_ENABLE(runtime, AS_HELP_STRING([--enable-runtime], [use the included runtime])) AS_IF([test x"$enable_runtime" != x"yes"], [ AS_IF([test x"$ac_cv_header_objc_objc_h" = x"yes"], [ dnl TODO: This is ugly. Let's think of a better check. AC_EGREP_CPP(yes, [ #import <objc/objc.h> #ifdef __objc_INCLUDE_GNU yes | > > > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | ]) objc_runtime="ObjFW runtime" AC_CHECK_HEADER(objc/objc.h) AC_MSG_CHECKING(which Objective C runtime to use) AC_ARG_ENABLE(runtime, AS_HELP_STRING([--enable-runtime], [use the included runtime])) AC_ARG_ENABLE(seluid16, AS_HELP_STRING([--enable-seluid16], [use only 16 bit for selectors UIDs])) AS_IF([test x"$enable_runtime" != x"yes"], [ AS_IF([test x"$ac_cv_header_objc_objc_h" = x"yes"], [ dnl TODO: This is ugly. Let's think of a better check. AC_EGREP_CPP(yes, [ #import <objc/objc.h> #ifdef __objc_INCLUDE_GNU yes |
︙ | ︙ | |||
210 211 212 213 214 215 216 217 218 219 220 221 222 223 | #endif ], [ AC_SUBST(LOOKUP_S, lookup-x86-elf.S) AC_DEFINE(OF_ASM_LOOKUP, 1, [Whether to use lookup in assembly]) ]) ]) ;; "Apple runtime") AC_DEFINE(OF_APPLE_RUNTIME, 1, [Whether we use the Apple ObjC runtime]) AC_CHECK_LIB(objc, objc_msgSend, [ LIBS="-lobjc $LIBS" | > > > > > | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | #endif ], [ AC_SUBST(LOOKUP_S, lookup-x86-elf.S) AC_DEFINE(OF_ASM_LOOKUP, 1, [Whether to use lookup in assembly]) ]) ]) AS_IF([test x"$enable_seluid16" = x"yes"], [ AC_DEFINE(OF_SELUID16, 1, [Whether to use 16 bit selector UIDs]) ]) ;; "Apple runtime") AC_DEFINE(OF_APPLE_RUNTIME, 1, [Whether we use the Apple ObjC runtime]) AC_CHECK_LIB(objc, objc_msgSend, [ LIBS="-lobjc $LIBS" |
︙ | ︙ |
Modified src/runtime/lookup-amd64-elf.S from [a0fef4c085] to [09c8f5af4a].
︙ | ︙ | |||
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 | * 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. */ .globl objc_msg_lookup .globl objc_msg_lookup_super .section .text objc_msg_lookup: testq %rdi, %rdi jz ret_nil movq (%rdi), %r8 movq 64(%r8), %r8 lookup: movq (%rsi), %rax movzbl %ah, %ecx movzbl %al, %edx shrl $16, %eax movq (%r8,%rax,8), %r8 movq (%r8,%rcx,8), %r8 movq (%r8,%rdx,8), %rax testq %rax, %rax jz forward ret | > > > > | 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 | * 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" .globl objc_msg_lookup .globl objc_msg_lookup_super .section .text objc_msg_lookup: testq %rdi, %rdi jz ret_nil movq (%rdi), %r8 movq 64(%r8), %r8 lookup: movq (%rsi), %rax movzbl %ah, %ecx movzbl %al, %edx #ifndef OF_SELUID16 shrl $16, %eax movq (%r8,%rax,8), %r8 #endif movq (%r8,%rcx,8), %r8 movq (%r8,%rdx,8), %rax testq %rax, %rax jz forward ret |
︙ | ︙ |
Modified src/runtime/lookup-x86-elf.S from [cafa9c173a] to [d301a0d068].
︙ | ︙ | |||
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 | * 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. */ .globl objc_msg_lookup .globl objc_msg_lookup_super .section .text objc_msg_lookup: movl 4(%esp), %edx testl %edx, %edx jz ret_nil movl (%edx), %edx movl 32(%edx), %edx lookup: movl 8(%esp), %eax movzbl 2(%eax), %ecx movl (%edx,%ecx,4), %edx movzbl 1(%eax), %ecx movl (%edx,%ecx,4), %edx movzbl (%eax), %ecx movl (%edx,%ecx,4), %eax testl %eax, %eax jz forward | > > > > | 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 | * 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" .globl objc_msg_lookup .globl objc_msg_lookup_super .section .text objc_msg_lookup: movl 4(%esp), %edx testl %edx, %edx jz ret_nil movl (%edx), %edx movl 32(%edx), %edx lookup: movl 8(%esp), %eax #ifndef OF_SELUID16 movzbl 2(%eax), %ecx movl (%edx,%ecx,4), %edx #endif movzbl 1(%eax), %ecx movl (%edx,%ecx,4), %edx movzbl (%eax), %ecx movl (%edx,%ecx,4), %eax testl %eax, %eax jz forward |
︙ | ︙ |
Modified src/runtime/runtime-private.h from [7dea8609ad] to [33a45d5cce].
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | struct objc_hashtable_bucket **data; }; struct objc_sparsearray { struct objc_sparsearray_level2 *buckets[256]; }; struct objc_sparsearray_level2 { struct objc_sparsearray_level3 *buckets[256]; BOOL empty; }; struct objc_sparsearray_level3 { const void *buckets[256]; BOOL empty; }; enum objc_abi_class_info { OBJC_CLASS_INFO_CLASS = 0x001, OBJC_CLASS_INFO_METACLASS = 0x002, OBJC_CLASS_INFO_SETUP = 0x100, OBJC_CLASS_INFO_LOADED = 0x200, OBJC_CLASS_INFO_INITIALIZED = 0x400 | > > > > > > > > | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | struct objc_hashtable_bucket **data; }; struct objc_sparsearray { struct objc_sparsearray_level2 *buckets[256]; }; #ifndef OF_SELUID16 struct objc_sparsearray_level2 { struct objc_sparsearray_level3 *buckets[256]; BOOL empty; }; struct objc_sparsearray_level3 { const void *buckets[256]; BOOL empty; }; #else struct objc_sparsearray_level2 { const void *buckets[256]; BOOL empty; }; #endif enum objc_abi_class_info { OBJC_CLASS_INFO_CLASS = 0x001, OBJC_CLASS_INFO_METACLASS = 0x002, OBJC_CLASS_INFO_SETUP = 0x100, OBJC_CLASS_INFO_LOADED = 0x200, OBJC_CLASS_INFO_INITIALIZED = 0x400 |
︙ | ︙ | |||
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | extern void objc_global_mutex_unlock(void); extern void objc_global_mutex_free(void); extern void objc_free_when_singlethreaded(void*); static inline const void* objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx) { uint8_t i = idx >> 16; uint8_t j = idx >> 8; uint8_t k = idx; return s->buckets[i]->buckets[j]->buckets[k]; } #define ERROR(...) \ { \ fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__); \ fprintf(stderr, __VA_ARGS__); \ fputs("\n", stderr); \ abort(); \ } | > > > > > > > | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | extern void objc_global_mutex_unlock(void); extern void objc_global_mutex_free(void); extern void objc_free_when_singlethreaded(void*); static inline const void* objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx) { #ifndef OF_SELUID16 uint8_t i = idx >> 16; uint8_t j = idx >> 8; uint8_t k = idx; return s->buckets[i]->buckets[j]->buckets[k]; #else uint8_t i = idx >> 8; uint8_t j = idx; return s->buckets[i]->buckets[j]; #endif } #define ERROR(...) \ { \ fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__); \ fprintf(stderr, __VA_ARGS__); \ fputs("\n", stderr); \ abort(); \ } |
Modified src/runtime/selector.m from [f394a43240] to [d31a7805ef].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <stdio.h> #include <stdlib.h> #include <string.h> #import "runtime.h" #import "runtime-private.h" static struct objc_sparsearray *selectors = NULL; void objc_register_selector(struct objc_abi_selector *sel) { uint32_t hash, last; struct objc_selector *rsel = (struct objc_selector*)sel; const char *name; if (selectors == NULL) selectors = objc_sparsearray_new(); | > > > > > > | | | | 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 | #include <stdio.h> #include <stdlib.h> #include <string.h> #import "runtime.h" #import "runtime-private.h" #ifndef OF_SELUID16 # define SEL_MAX 0xFFFFFF #else # define SEL_MAX 0xFFFF #endif static struct objc_sparsearray *selectors = NULL; void objc_register_selector(struct objc_abi_selector *sel) { uint32_t hash, last; struct objc_selector *rsel = (struct objc_selector*)sel; const char *name; if (selectors == NULL) selectors = objc_sparsearray_new(); hash = objc_hash_string(sel->name) & SEL_MAX; while (hash <= SEL_MAX && (name = objc_sparsearray_get(selectors, hash)) != NULL) { if (!strcmp(name, sel->name)) { rsel->uid = hash; return; } hash++; } if (hash > SEL_MAX) { last = hash; hash = 0; while (hash < last && (name = objc_sparsearray_get(selectors, hash)) != NULL) { if (!strcmp(name, sel->name)) { rsel->uid = hash; |
︙ | ︙ |
Modified src/runtime/sparsearray.m from [676c05892e] to [55b9165add].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <stdio.h> #include <stdlib.h> #import "runtime.h" #import "runtime-private.h" static struct objc_sparsearray_level2 *empty_level2 = NULL; static struct objc_sparsearray_level3 *empty_level3 = NULL; static void init(void) { uint_fast16_t i; empty_level2 = malloc(sizeof(struct objc_sparsearray_level2)); | > > < < | > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | #include <stdio.h> #include <stdlib.h> #import "runtime.h" #import "runtime-private.h" static struct objc_sparsearray_level2 *empty_level2 = NULL; #ifndef OF_SELUID16 static struct objc_sparsearray_level3 *empty_level3 = NULL; #endif static void init(void) { uint_fast16_t i; empty_level2 = malloc(sizeof(struct objc_sparsearray_level2)); if (empty_level2 == NULL) ERROR("Not enough memory to allocate sparse array!"); empty_level2->empty = YES; #ifndef OF_SELUID16 empty_level3 = malloc(sizeof(struct objc_sparsearray_level3)); if (empty_level3 == NULL) ERROR("Not enough memory to allocate sparse array!"); empty_level3->empty = YES; #endif #ifndef OF_SELUID16 for (i = 0; i < 256; i++) { empty_level2->buckets[i] = empty_level3; empty_level3->buckets[i] = NULL; } #else for (i = 0; i < 256; i++) empty_level2->buckets[i] = NULL; #endif } struct objc_sparsearray* objc_sparsearray_new(void) { struct objc_sparsearray *s; uint_fast16_t i; #ifndef OF_SELUID16 if (empty_level2 == NULL || empty_level3 == NULL) init(); #else if (empty_level2 == NULL) init(); #endif if ((s = malloc(sizeof(struct objc_sparsearray))) == NULL) ERROR("Not enough memory to allocate sparse array!"); for (i = 0; i < 256; i++) s->buckets[i] = empty_level2; return s; } void objc_sparsearray_copy(struct objc_sparsearray *dst, struct objc_sparsearray *src) { uint_fast16_t i, j; #ifndef OF_SELUID16 uint_fast16_t k; #endif uint32_t idx; for (i = 0; i < 256; i++) { if (src->buckets[i]->empty) continue; #ifndef OF_SELUID16 for (j = 0; j < 256; j++) { if (src->buckets[i]->buckets[j]->empty) continue; for (k = 0; k < 256; k++) { const void *obj; obj = src->buckets[i]->buckets[j]->buckets[k]; if (obj == NULL) continue; idx = (i << 16) | (j << 8) | k; objc_sparsearray_set(dst, idx, obj); } } #else for (j = 0; j < 256; j++) { const void *obj; obj = src->buckets[i]->buckets[j]; if (obj == NULL) continue; idx = (i << 8) | j; objc_sparsearray_set(dst, idx, obj); } #endif } } void objc_sparsearray_set(struct objc_sparsearray *s, uint32_t idx, const void *obj) { #ifndef OF_SELUID16 uint8_t i = idx >> 16; uint8_t j = idx >> 8; uint8_t k = idx; #else uint8_t i = idx >> 8; uint8_t j = idx; #endif if (s->buckets[i]->empty) { struct objc_sparsearray_level2 *t; uint_fast16_t l; t = malloc(sizeof(struct objc_sparsearray_level2)); if (t == NULL) ERROR("Not enough memory to insert into sparse array!"); t->empty = NO; for (l = 0; l < 256; l++) #ifndef OF_SELUID16 t->buckets[l] = empty_level3; #else t->buckets[l] = NULL; #endif s->buckets[i] = t; } #ifndef OF_SELUID16 if (s->buckets[i]->buckets[j]->empty) { struct objc_sparsearray_level3 *t; uint_fast16_t l; t = malloc(sizeof(struct objc_sparsearray_level3)); if (t == NULL) ERROR("Not enough memory to insert into sparse array!"); t->empty = NO; for (l = 0; l < 256; l++) t->buckets[l] = NULL; s->buckets[i]->buckets[j] = t; } s->buckets[i]->buckets[j]->buckets[k] = obj; #else s->buckets[i]->buckets[j] = obj; #endif } void objc_sparsearray_free(struct objc_sparsearray *s) { uint_fast16_t i; #ifndef OF_SELUID16 uint_fast16_t j; #endif for (i = 0; i < 256; i++) { #ifndef OF_SELUID16 if (s->buckets[i]->empty) continue; for (j = 0; j < 256; j++) if (!s->buckets[i]->buckets[j]->empty) free(s->buckets[i]->buckets[j]); #endif free(s->buckets[i]); } free(s); } void objc_sparsearray_cleanup(void) { if (empty_level2 != NULL) free(empty_level2); #ifndef OF_SELUID16 if (empty_level3 != NULL) free(empty_level3); #endif empty_level2 = NULL; #ifndef OF_SELUID16 empty_level3 = NULL; #endif } |