1
/* Basic data types for Objective C.
2
Copyright (C) 1998 Free Software Foundation, Inc.
3
Contributed by Ovidiu Predescu.
5
This file is part of GNU CC.
7
GNU CC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
GNU CC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with GNU CC; see the file COPYING. If not, write to
19
the Free Software Foundation, 59 Temple Place - Suite 330,
20
Boston, MA 02111-1307, USA. */
22
/* As a special exception, if you link this library with files
23
compiled with GCC to produce an executable, this does not cause
24
the resulting executable to be covered by the GNU General Public License.
25
This exception does not however invalidate any other reasons why
26
the executable file might be covered by the GNU General Public License. */
28
#include "compiler-info.h"
40
/* gc_typed.h uses the following but doesn't declare them */
42
typedef GC_signed_word signed_word;
44
#if BITS_PER_WORD == 32
46
# define modWORDSZ(n) ((n) & 0x1f) /* n mod size of word */
49
#if BITS_PER_WORD == 64
51
# define modWORDSZ(n) ((n) & 0x3f) /* n mod size of word */
54
#define divWORDSZ(n) ((n) >> LOGWL) /* divide n by size of word */
56
#include "gc/gc_typed.h"
58
/* The following functions set up in `mask` the corresponding pointers.
59
The offset is incremented with the size of the type. */
62
({ typeof(V) __v=(V); typeof(A) __a=(A); \
63
__a*((__v+__a-1)/__a); })
65
#define SET_BIT_FOR_OFFSET(mask, offset) \
66
GC_set_bit(mask, offset / sizeof (void*))
70
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
72
__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
76
__objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
81
printf("WARNING: %s got NULL type.\n", __PRETTY_FUNCTION__);
87
while (isdigit(*++type))
88
/* do nothing */; /* skip the size of the array */
92
for (i = 0; i < len; i++)
93
__objc_gc_setup_array (mask, type, offset);
97
for (i = 0; i < len; i++)
98
__objc_gc_setup_struct (mask, type, offset);
102
for (i = 0; i < len; i++)
103
__objc_gc_setup_union (mask, type, offset);
112
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
114
struct objc_struct_layout layout;
115
unsigned int position;
119
printf("WARNING: %s got NULL type.\n", __PRETTY_FUNCTION__);
123
objc_layout_structure (type, &layout);
125
while (objc_layout_structure_next_member (&layout))
127
BOOL gc_invisible = NO;
129
objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
131
/* Skip the variable name */
134
for (mtype++; *mtype++ != '"';)
138
if (*mtype == _C_GCINVISIBLE)
144
/* Add to position the offset of this structure */
155
SET_BIT_FOR_OFFSET(mask, position);
159
__objc_gc_setup_array (mask, mtype, position);
163
__objc_gc_setup_struct (mask, mtype, position);
167
__objc_gc_setup_union (mask, mtype, position);
177
__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
179
/* Sub-optimal, quick implementation: assume the union is made of
180
pointers, set up the mask accordingly. */
185
printf("WARNING: %s got NULL type.\n", __PRETTY_FUNCTION__);
189
/* Skip the variable name */
192
for (type++; *type++ != '"';)
196
size = objc_sizeof_type (type);
197
align = objc_alignof_type (type);
199
offset = ROUND(offset, align);
200
for (i = 0; i < size; i += sizeof (void*))
202
SET_BIT_FOR_OFFSET(mask, offset);
203
offset += sizeof (void*);
208
/* Iterates over the types in the structure that represents the class
209
encoding and sets the bits in mask according to each ivar type. */
211
__objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
213
struct objc_struct_layout layout;
214
unsigned int offset, align;
215
const char *ivar_type;
218
printf("WARNING: %s got NULL type.\n", __PRETTY_FUNCTION__);
222
objc_layout_structure (type, &layout);
224
while (objc_layout_structure_next_member (&layout)) {
225
BOOL gc_invisible = NO;
227
objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
229
/* Skip the variable name */
230
if (*ivar_type == '"') {
231
for (ivar_type++; *ivar_type++ != '"';)
235
if (*ivar_type == _C_GCINVISIBLE) {
240
switch (*ivar_type) {
247
SET_BIT_FOR_OFFSET(mask, offset);
251
__objc_gc_setup_array (mask, ivar_type, offset);
255
__objc_gc_setup_struct (mask, ivar_type, offset);
259
__objc_gc_setup_union (mask, ivar_type, offset);
268
/* Computes in *type the full type encoding of this class including
269
its super classes. '*size' gives the total number of bytes allocated
270
into *type, '*current' the number of bytes used so far by the
273
__objc_class_structure_encoding (Class class, char **type, int *size,
277
struct objc_ivar_list* ivars;
280
// Root class, add '{'
286
/* Add the type encodings of the super classes */
287
__objc_class_structure_encoding (class->super_class, type, size, current);
289
ivars = class->ivars;
293
ivar_count = ivars->ivar_count;
295
for (i = 0; i < ivar_count; i++) {
296
struct objc_ivar *ivar = &(ivars->ivar_list[i]);
297
const char *ivar_type = ivar->ivar_type;
298
int len = strlen (ivar_type);
300
if (*current + len + 1 >= *size)
302
/* Increase the size of the encoding string so that it
303
contains this ivar's type. */
304
*size = ROUND(*current + len + 1, 10);
305
*type = objc_realloc (*type, *size);
307
strcat (*type + *current, ivar_type);
313
/* Allocates the memory that will hold the type description for class
314
and calls the __objc_class_structure_encoding that generates this
316
void __objc_generate_gc_type_description (Class class)
318
GC_bitmap mask = NULL;
322
char *class_structure_type = NULL;
324
if (!CLS_ISCLASS(class))
327
/* We have to create a mask in which each bit counts for a pointer member.
328
We take into consideration all the non-pointer instance variables and we
329
round them up to the alignment. */
331
//class_structure_type = objc_atomic_malloc (type_size);
332
class_structure_type = GC_MALLOC_ATOMIC(1024);
333
class_structure_type[0] = '\0';
334
__objc_class_structure_encoding (class,
335
&class_structure_type,
338
//if (current + 1 == type_size)
339
// class_structure_type = objc_realloc (class_structure_type, ++type_size);
340
// add root class suffix
341
strcat (class_structure_type + current, "}");
343
if (class_structure_type[0] != '{') {
344
printf("ERROR: invalid class type '%s'",
345
class_structure_type ? class_structure_type : "<NULL>");
348
if (class_structure_type[strlen(class_structure_type) - 1] != '}') {
349
printf("ERROR: invalid class type '%s'",
350
class_structure_type ? class_structure_type : "<NULL>");
355
printf ("type description for '%s' is %s\n",
356
class->name ? class->name : "<NULL>",
357
class_structure_type ? class_structure_type : "<NULL>");
360
if (class_structure_type == NULL) {
361
printf("WARNING: %s got NULL type for class %s.\n",
362
__PRETTY_FUNCTION__, class->name ? class->name : "<NULL>");
366
/* The number of bits in the mask is the size of an instance in bytes divided
367
by the size of a pointer. */
368
bits_no = (ROUND(class_get_instance_size (class), sizeof(void*))
370
size = ROUND(bits_no, BITS_PER_WORD) / BITS_PER_WORD;
371
mask = GC_MALLOC_ATOMIC(size * sizeof (int));
372
memset(mask, 0, size * sizeof (int));
374
__objc_gc_type_description_from_type (mask, class_structure_type);
375
class_structure_type = NULL;
378
printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
379
class_structure_type ? class_structure_type : "<NULL>",
380
class->name ? class->name : "<NULL>",
384
for (i = 0; i < size; i++)
385
printf (" %lx", mask[i]);
390
class->gc_object_type = (void*)GC_make_descriptor (mask, bits_no);
394
/* Returns YES if type denotes a pointer type, NO otherwise */
395
static __inline__ BOOL __objc_ivar_pointer (register const char *type)
397
type = objc_skip_type_qualifiers (type);
399
return (*type == _C_ID
403
|| *type == _C_CHARPTR
404
|| *type == _C_ATOM);
408
/* Mark the instance variable whose name is given by ivarname as a
409
weak pointer (a pointer hidden to the garbage collector) if
410
gc_invisible is true. If gc_invisible is false it unmarks the
411
instance variable and makes it a normal pointer, visible to the
414
This operation only makes sense on instance variables that are
417
class_ivar_set_gcinvisible (Class class, const char* ivarname,
421
struct objc_ivar_list* ivars;
423
if (!class || !ivarname)
426
ivars = class->ivars;
430
ivar_count = ivars->ivar_count;
432
for (i = 0; i < ivar_count; i++)
434
struct objc_ivar *ivar = &(ivars->ivar_list[i]);
437
if (!ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
440
assert (ivar->ivar_type);
441
type = ivar->ivar_type;
443
/* Skip the variable name */
446
for (type++; *type++ != '"';)
450
if (*type == _C_GCINVISIBLE)
454
if (gc_invisible || !__objc_ivar_pointer (type))
455
return; /* The type of the variable already matches the
456
requested gc_invisible type */
458
/* The variable is gc_invisible and we have to reverse it */
459
new_type = objc_atomic_malloc (strlen (ivar->ivar_type));
460
strncpy (new_type, ivar->ivar_type,
461
(size_t)(type - ivar->ivar_type));
462
strcat (new_type, type + 1);
463
ivar->ivar_type = new_type;
469
if (!gc_invisible || !__objc_ivar_pointer (type))
470
return; /* The type of the variable already matches the
471
requested gc_invisible type */
473
/* The variable is gc visible and we have to make it gc_invisible */
474
new_type = objc_malloc (strlen (ivar->ivar_type) + 2);
475
strncpy (new_type, ivar->ivar_type,
476
(size_t)(type - ivar->ivar_type));
477
strcat (new_type, "!");
478
strcat (new_type, type);
479
ivar->ivar_type = new_type;
482
__objc_generate_gc_type_description (class);
486
/* Search the instance variable in the superclasses */
487
class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
490
BOOL objc_ignore_leaks = YES;
491
void (*objc_report_atomic_leak_func)(void *ptr, unsigned size) = NULL;
492
void (*objc_report_composite_leak_func)(void *ptr, unsigned size) = NULL;
494
void objc_report_atomic_leak(void *ptr, unsigned size) {
495
const unsigned char *t;
496
unsigned char buffer[128];
498
if (objc_ignore_leaks) return;
499
if (objc_report_atomic_leak_func) {
500
objc_report_atomic_leak_func(ptr, size);
505
if (object_is_class(ptr))
507
else if (object_is_instance(ptr))
518
for (i = 0; i < size; i++) {
519
c = ((unsigned char *)ptr)[i];
520
if (c == '\0') break;
521
if (!((c > 31) && (c < 128)))
531
fprintf(stderr, "LEAK(atomic): %s 0x%08X %d bytes(%s)\n",
534
buffer ? buffer : "<NULL>");
536
void objc_report_composite_leak(void *ptr, unsigned size) {
538
unsigned char buffer[128];
540
if (objc_ignore_leaks) return;
541
if (objc_report_composite_leak_func) {
542
objc_report_composite_leak_func(ptr, size);
547
if (object_is_class(ptr))
549
else if (object_is_instance(ptr))
560
for (i = 0; i < size; i++) {
561
c = ((unsigned char *)ptr)[i];
562
if (c == '\0') break;
563
if (!((c > 31) && (c < 128)))
573
fprintf(stderr, "LEAK(composite): %s 0x%08X %d bytes(%s)\n",
576
buffer ? buffer : "<NULL>");
579
#else /* !OBJC_WITH_GC */
582
__objc_generate_gc_type_description (Class class)
586
void class_ivar_set_gcinvisible (Class class,
587
const char* ivarname,
592
#endif /* OBJC_WITH_GC */