diff options
Diffstat (limited to 'gcc-4.7/libobjc/gc.c')
-rw-r--r-- | gcc-4.7/libobjc/gc.c | 460 |
1 files changed, 0 insertions, 460 deletions
diff --git a/gcc-4.7/libobjc/gc.c b/gcc-4.7/libobjc/gc.c deleted file mode 100644 index d009230b7..000000000 --- a/gcc-4.7/libobjc/gc.c +++ /dev/null @@ -1,460 +0,0 @@ -/* Basic data types for Objective C. - Copyright (C) 1998, 2002, 2004, 2005, 2006, 2009, 2010 - Free Software Foundation, Inc. - Contributed by Ovidiu Predescu. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "objc-private/common.h" -#include "objc/objc.h" - -#if OBJC_WITH_GC - -#include "tconfig.h" -#include <assert.h> -#include <ctype.h> /* For isdigit. */ -#include <string.h> -#include <stdlib.h> -#include "objc/runtime.h" -#include "objc-private/module-abi-8.h" - -#include <gc.h> -#include <limits.h> - -/* gc_typed.h uses the following but doesn't declare them */ -typedef GC_word word; -typedef GC_signed_word signed_word; -#define BITS_PER_WORD (CHAR_BIT * sizeof (word)) - -#include <gc_typed.h> - -/* The following functions set up in `mask` the corresponding pointers. - The offset is incremented with the size of the type. */ - -#define ROUND(V, A) \ - ({ typeof (V) __v = (V); typeof (A) __a = (A); \ - __a * ((__v+__a - 1)/__a); }) - -#define SET_BIT_FOR_OFFSET(mask, offset) \ - GC_set_bit (mask, offset / sizeof (void *)) - -/* Some prototypes */ -static void -__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset); -static void -__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset); - - -static void -__objc_gc_setup_array (GC_bitmap mask, const char *type, int offset) -{ - int i, len = atoi (type + 1); - - while (isdigit (*++type)) - /* do nothing */; /* skip the size of the array */ - - switch (*type) { - case _C_ARY_B: - for (i = 0; i < len; i++) - __objc_gc_setup_array (mask, type, offset); - break; - - case _C_STRUCT_B: - for (i = 0; i < len; i++) - __objc_gc_setup_struct (mask, type, offset); - break; - - case _C_UNION_B: - for (i = 0; i < len; i++) - __objc_gc_setup_union (mask, type, offset); - break; - - default: - break; - } -} - -static void -__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset) -{ - struct objc_struct_layout layout; - unsigned int position; - const char *mtype; - - objc_layout_structure (type, &layout); - - while (objc_layout_structure_next_member (&layout)) - { - BOOL gc_invisible = NO; - - objc_layout_structure_get_info (&layout, &position, NULL, &mtype); - - /* Skip the variable name */ - if (*mtype == '"') - { - for (mtype++; *mtype++ != '"';) - /* do nothing */; - } - - if (*mtype == _C_GCINVISIBLE) - { - gc_invisible = YES; - mtype++; - } - - /* Add to position the offset of this structure */ - position += offset; - - switch (*mtype) { - case _C_ID: - case _C_CLASS: - case _C_SEL: - case _C_PTR: - case _C_CHARPTR: - case _C_ATOM: - if (! gc_invisible) - SET_BIT_FOR_OFFSET (mask, position); - break; - - case _C_ARY_B: - __objc_gc_setup_array (mask, mtype, position); - break; - - case _C_STRUCT_B: - __objc_gc_setup_struct (mask, mtype, position); - break; - - case _C_UNION_B: - __objc_gc_setup_union (mask, mtype, position); - break; - - default: - break; - } - } -} - -static void -__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset) -{ - /* Sub-optimal, quick implementation: assume the union is made of - pointers, set up the mask accordingly. */ - - int i, size, align; - - /* Skip the variable name */ - if (*type == '"') - { - for (type++; *type++ != '"';) - /* do nothing */; - } - - size = objc_sizeof_type (type); - align = objc_alignof_type (type); - - offset = ROUND (offset, align); - for (i = 0; i < size; i += sizeof (void *)) - { - SET_BIT_FOR_OFFSET (mask, offset); - offset += sizeof (void *); - } -} - - -/* Iterates over the types in the structure that represents the class - encoding and sets the bits in mask according to each ivar type. */ -static void -__objc_gc_type_description_from_type (GC_bitmap mask, const char *type) -{ - struct objc_struct_layout layout; - unsigned int offset, align; - const char *ivar_type; - - objc_layout_structure (type, &layout); - - while (objc_layout_structure_next_member (&layout)) - { - BOOL gc_invisible = NO; - - objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type); - - /* Skip the variable name */ - if (*ivar_type == '"') - { - for (ivar_type++; *ivar_type++ != '"';) - /* do nothing */; - } - - if (*ivar_type == _C_GCINVISIBLE) - { - gc_invisible = YES; - ivar_type++; - } - - switch (*ivar_type) { - case _C_ID: - case _C_CLASS: - case _C_SEL: - case _C_PTR: - case _C_CHARPTR: - if (! gc_invisible) - SET_BIT_FOR_OFFSET (mask, offset); - break; - - case _C_ARY_B: - __objc_gc_setup_array (mask, ivar_type, offset); - break; - - case _C_STRUCT_B: - __objc_gc_setup_struct (mask, ivar_type, offset); - break; - - case _C_UNION_B: - __objc_gc_setup_union (mask, ivar_type, offset); - break; - - default: - break; - } - } -} - -/* Computes in *type the full type encoding of this class including - its super classes. '*size' gives the total number of bytes allocated - into *type, '*current' the number of bytes used so far by the - encoding. */ -static void -__objc_class_structure_encoding (Class class, char **type, int *size, - int *current) -{ - int i, ivar_count; - struct objc_ivar_list *ivars; - - if (! class) - { - strcat (*type, "{"); - (*current)++; - return; - } - - /* Add the type encodings of the super classes */ - __objc_class_structure_encoding (class->super_class, type, size, current); - - ivars = class->ivars; - if (! ivars) - return; - - ivar_count = ivars->ivar_count; - - for (i = 0; i < ivar_count; i++) - { - struct objc_ivar *ivar = &(ivars->ivar_list[i]); - const char *ivar_type = ivar->ivar_type; - int len = strlen (ivar_type); - - if (*current + len + 1 >= *size) - { - /* Increase the size of the encoding string so that it - contains this ivar's type. */ - *size = ROUND (*current + len + 1, 10); - *type = objc_realloc (*type, *size); - } - strcat (*type + *current, ivar_type); - *current += len; - } -} - - -/* Allocates the memory that will hold the type description for class - and calls the __objc_class_structure_encoding that generates this - value. */ -void -__objc_generate_gc_type_description (Class class) -{ - GC_bitmap mask; - int bits_no, size; - int type_size = 10, current; - char *class_structure_type; - - if (! CLS_ISCLASS (class)) - return; - - /* We have to create a mask in which each bit counts for a pointer member. - We take into consideration all the non-pointer instance variables and we - round them up to the alignment. */ - - /* The number of bits in the mask is the size of an instance in bytes divided - by the size of a pointer. */ - bits_no = (ROUND (class_getInstanceSize (class), sizeof (void *)) - / sizeof (void *)); - size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD; - mask = objc_atomic_malloc (size * sizeof (int)); - memset (mask, 0, size * sizeof (int)); - - class_structure_type = objc_atomic_malloc (type_size); - *class_structure_type = current = 0; - __objc_class_structure_encoding (class, &class_structure_type, - &type_size, ¤t); - if (current + 1 == type_size) - class_structure_type = objc_realloc (class_structure_type, ++type_size); - strcat (class_structure_type + current, "}"); -#ifdef DEBUG - printf ("type description for '%s' is %s\n", class->name, class_structure_type); -#endif - - __objc_gc_type_description_from_type (mask, class_structure_type); - objc_free (class_structure_type); - -#ifdef DEBUG - printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:", - class_structure_type, class->name, bits_no, size); - { - int i; - for (i = 0; i < size; i++) - printf (" %lx", mask[i]); - } - puts (""); -#endif - - class->gc_object_type = (void *) GC_make_descriptor (mask, bits_no); -} - - -/* Returns YES if type denotes a pointer type, NO otherwise */ -static inline BOOL -__objc_ivar_pointer (const char *type) -{ - type = objc_skip_type_qualifiers (type); - - return (*type == _C_ID - || *type == _C_CLASS - || *type == _C_SEL - || *type == _C_PTR - || *type == _C_CHARPTR - || *type == _C_ATOM); -} - - -/* Mark the instance variable whose name is given by ivarname as a - weak pointer (a pointer hidden to the garbage collector) if - gc_invisible is true. If gc_invisible is false it unmarks the - instance variable and makes it a normal pointer, visible to the - garbage collector. - - This operation only makes sense on instance variables that are - pointers. */ -void -class_ivar_set_gcinvisible (Class class, const char *ivarname, - BOOL gc_invisible) -{ - int i, ivar_count; - struct objc_ivar_list *ivars; - - if (! class || ! ivarname) - return; - - ivars = class->ivars; - if (! ivars) - return; - - ivar_count = ivars->ivar_count; - - for (i = 0; i < ivar_count; i++) - { - struct objc_ivar *ivar = &(ivars->ivar_list[i]); - const char *type; - - if (! ivar->ivar_name || strcmp (ivar->ivar_name, ivarname)) - continue; - - assert (ivar->ivar_type); - type = ivar->ivar_type; - - /* Skip the variable name */ - if (*type == '"') - { - for (type++; *type++ != '"';) - /* do nothing */; - } - - if (*type == _C_GCINVISIBLE) - { - char *new_type; - size_t len; - - if (gc_invisible || ! __objc_ivar_pointer (type)) - return; /* The type of the variable already matches the - requested gc_invisible type */ - - /* The variable is gc_invisible so we make it gc visible. */ - new_type = objc_atomic_malloc (strlen(ivar->ivar_type)); - len = (type - ivar->ivar_type); - memcpy (new_type, ivar->ivar_type, len); - new_type[len] = 0; - strcat (new_type, type + 1); - ivar->ivar_type = new_type; - } - else - { - char *new_type; - size_t len; - - if (! gc_invisible || ! __objc_ivar_pointer (type)) - return; /* The type of the variable already matches the - requested gc_invisible type */ - - /* The variable is gc visible so we make it gc_invisible. */ - new_type = objc_malloc (strlen(ivar->ivar_type) + 2); - - /* Copy the variable name. */ - len = (type - ivar->ivar_type); - memcpy (new_type, ivar->ivar_type, len); - /* Add '!'. */ - new_type[len++] = _C_GCINVISIBLE; - /* Copy the original types. */ - strcpy (new_type + len, type); - - ivar->ivar_type = new_type; - } - - __objc_generate_gc_type_description (class); - return; - } - - /* Search the instance variable in the superclasses */ - class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible); -} - -#else /* !OBJC_WITH_GC */ - -void -__objc_generate_gc_type_description (Class class __attribute__ ((__unused__))) -{ -} - -void class_ivar_set_gcinvisible (Class class __attribute__ ((__unused__)), - const char *ivarname __attribute__ ((__unused__)), - BOOL gc_invisible __attribute__ ((__unused__))) -{ -} - -#endif /* OBJC_WITH_GC */ |