OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libobjc/] [gc.c] - Blame information for rev 18

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* Basic data types for Objective C.
2
   Copyright (C) 1998, 2002 Free Software Foundation, Inc.
3
   Contributed by Ovidiu Predescu.
4
 
5
This file is part of GCC.
6
 
7
GCC 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)
10
any later version.
11
 
12
GCC 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.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to
19
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20
Boston, MA 02110-1301, USA.  */
21
 
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.  */
27
 
28
#include "tconfig.h"
29
#include "objc/objc.h"
30
#include "objc/encoding.h"
31
 
32
#include <assert.h>
33
#include <string.h>
34
#include <stdlib.h>
35
 
36
#if OBJC_WITH_GC
37
 
38
#include <gc.h>
39
#include <limits.h>
40
 
41
/* gc_typed.h uses the following but doesn't declare them */
42
typedef GC_word word;
43
typedef GC_signed_word signed_word;
44
#define BITS_PER_WORD (CHAR_BIT * sizeof (word))
45
 
46
#include <gc_typed.h>
47
 
48
/* The following functions set up in `mask` the corresponding pointers.
49
   The offset is incremented with the size of the type.  */
50
 
51
#define ROUND(V, A) \
52
  ({ typeof (V) __v = (V); typeof (A) __a = (A); \
53
     __a * ((__v+__a - 1)/__a); })
54
 
55
#define SET_BIT_FOR_OFFSET(mask, offset) \
56
  GC_set_bit (mask, offset / sizeof (void *))
57
 
58
/* Some prototypes */
59
static void
60
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
61
static void
62
__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
63
 
64
 
65
static void
66
__objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
67
{
68
  int i, len = atoi (type + 1);
69
 
70
  while (isdigit (*++type))
71
    /* do nothing */;           /* skip the size of the array */
72
 
73
  switch (*type) {
74
  case _C_ARY_B:
75
    for (i = 0; i < len; i++)
76
      __objc_gc_setup_array (mask, type, offset);
77
    break;
78
 
79
  case _C_STRUCT_B:
80
    for (i = 0; i < len; i++)
81
      __objc_gc_setup_struct (mask, type, offset);
82
    break;
83
 
84
  case _C_UNION_B:
85
    for (i = 0; i < len; i++)
86
      __objc_gc_setup_union (mask, type, offset);
87
    break;
88
 
89
  default:
90
    break;
91
  }
92
}
93
 
94
static void
95
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
96
{
97
  struct objc_struct_layout layout;
98
  unsigned int position;
99
  const char *mtype;
100
 
101
  objc_layout_structure (type, &layout);
102
 
103
  while (objc_layout_structure_next_member (&layout))
104
    {
105
      BOOL gc_invisible = NO;
106
 
107
      objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
108
 
109
      /* Skip the variable name */
110
      if (*mtype == '"')
111
        {
112
          for (mtype++; *mtype++ != '"';)
113
            /* do nothing */;
114
        }
115
 
116
      if (*mtype == _C_GCINVISIBLE)
117
        {
118
          gc_invisible = YES;
119
          mtype++;
120
        }
121
 
122
      /* Add to position the offset of this structure */
123
      position += offset;
124
 
125
      switch (*mtype) {
126
      case _C_ID:
127
      case _C_CLASS:
128
      case _C_SEL:
129
      case _C_PTR:
130
      case _C_CHARPTR:
131
      case _C_ATOM:
132
        if (! gc_invisible)
133
          SET_BIT_FOR_OFFSET (mask, position);
134
        break;
135
 
136
      case _C_ARY_B:
137
        __objc_gc_setup_array (mask, mtype, position);
138
        break;
139
 
140
      case _C_STRUCT_B:
141
        __objc_gc_setup_struct (mask, mtype, position);
142
        break;
143
 
144
      case _C_UNION_B:
145
        __objc_gc_setup_union (mask, mtype, position);
146
        break;
147
 
148
      default:
149
        break;
150
      }
151
    }
152
}
153
 
154
static void
155
__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
156
{
157
  /* Sub-optimal, quick implementation: assume the union is made of
158
     pointers, set up the mask accordingly. */
159
 
160
  int i, size, align;
161
 
162
  /* Skip the variable name */
163
  if (*type == '"')
164
    {
165
      for (type++; *type++ != '"';)
166
        /* do nothing */;
167
    }
168
 
169
  size = objc_sizeof_type (type);
170
  align = objc_alignof_type (type);
171
 
172
  offset = ROUND (offset, align);
173
  for (i = 0; i < size; i += sizeof (void *))
174
    {
175
      SET_BIT_FOR_OFFSET (mask, offset);
176
      offset += sizeof (void *);
177
    }
178
}
179
 
180
 
181
/* Iterates over the types in the structure that represents the class
182
   encoding and sets the bits in mask according to each ivar type.  */
183
static void
184
__objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
185
{
186
  struct objc_struct_layout layout;
187
  unsigned int offset, align;
188
  const char *ivar_type;
189
 
190
  objc_layout_structure (type, &layout);
191
 
192
  while (objc_layout_structure_next_member (&layout))
193
    {
194
      BOOL gc_invisible = NO;
195
 
196
      objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
197
 
198
      /* Skip the variable name */
199
      if (*ivar_type == '"')
200
        {
201
          for (ivar_type++; *ivar_type++ != '"';)
202
            /* do nothing */;
203
        }
204
 
205
      if (*ivar_type == _C_GCINVISIBLE)
206
        {
207
          gc_invisible = YES;
208
          ivar_type++;
209
        }
210
 
211
      switch (*ivar_type) {
212
      case _C_ID:
213
      case _C_CLASS:
214
      case _C_SEL:
215
      case _C_PTR:
216
      case _C_CHARPTR:
217
        if (! gc_invisible)
218
          SET_BIT_FOR_OFFSET (mask, offset);
219
        break;
220
 
221
      case _C_ARY_B:
222
        __objc_gc_setup_array (mask, ivar_type, offset);
223
        break;
224
 
225
      case _C_STRUCT_B:
226
        __objc_gc_setup_struct (mask, ivar_type, offset);
227
        break;
228
 
229
      case _C_UNION_B:
230
        __objc_gc_setup_union (mask, ivar_type, offset);
231
        break;
232
 
233
      default:
234
        break;
235
      }
236
    }
237
}
238
 
239
/* Computes in *type the full type encoding of this class including
240
   its super classes. '*size' gives the total number of bytes allocated
241
   into *type, '*current' the number of bytes used so far by the
242
   encoding. */
243
static void
244
__objc_class_structure_encoding (Class class, char **type, int *size,
245
                                 int *current)
246
{
247
  int i, ivar_count;
248
  struct objc_ivar_list *ivars;
249
 
250
  if (! class)
251
    {
252
      strcat (*type, "{");
253
      *current++;
254
      return;
255
    }
256
 
257
  /* Add the type encodings of the super classes */
258
  __objc_class_structure_encoding (class->super_class, type, size, current);
259
 
260
  ivars = class->ivars;
261
  if (! ivars)
262
    return;
263
 
264
  ivar_count = ivars->ivar_count;
265
 
266
  for (i = 0; i < ivar_count; i++)
267
    {
268
      struct objc_ivar *ivar = &(ivars->ivar_list[i]);
269
      const char *ivar_type = ivar->ivar_type;
270
      int len = strlen (ivar_type);
271
 
272
      if (*current + len + 1 >= *size)
273
        {
274
          /* Increase the size of the encoding string so that it
275
             contains this ivar's type. */
276
          *size = ROUND (*current + len + 1, 10);
277
          *type = objc_realloc (*type, *size);
278
        }
279
      strcat (*type + *current, ivar_type);
280
      *current += len;
281
    }
282
}
283
 
284
 
285
/* Allocates the memory that will hold the type description for class
286
   and calls the __objc_class_structure_encoding that generates this
287
   value. */
288
void
289
__objc_generate_gc_type_description (Class class)
290
{
291
  GC_bitmap mask;
292
  int bits_no, size;
293
  int type_size = 10, current;
294
  char *class_structure_type;
295
 
296
  if (! CLS_ISCLASS (class))
297
    return;
298
 
299
  /* We have to create a mask in which each bit counts for a pointer member.
300
     We take into consideration all the non-pointer instance variables and we
301
     round them up to the alignment. */
302
 
303
  /* The number of bits in the mask is the size of an instance in bytes divided
304
     by the size of a pointer. */
305
  bits_no = (ROUND (class_get_instance_size (class), sizeof (void *))
306
             / sizeof (void *));
307
  size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
308
  mask = objc_atomic_malloc (size * sizeof (int));
309
  memset (mask, 0, size * sizeof (int));
310
 
311
  class_structure_type = objc_atomic_malloc (type_size);
312
  *class_structure_type = current = 0;
313
  __objc_class_structure_encoding (class, &class_structure_type,
314
                                   &type_size, &current);
315
  if (current + 1 == type_size)
316
    class_structure_type = objc_realloc (class_structure_type, ++type_size);
317
  strcat (class_structure_type + current, "}");
318
#ifdef DEBUG
319
  printf ("type description for '%s' is %s\n", class->name, class_structure_type);
320
#endif
321
 
322
  __objc_gc_type_description_from_type (mask, class_structure_type);
323
  objc_free (class_structure_type);
324
 
325
#ifdef DEBUG
326
  printf ("  mask for '%s', type '%s' (bits %d, mask size %d) is:",
327
          class_structure_type, class->name, bits_no, size);
328
  {
329
    int i;
330
    for (i = 0; i < size; i++)
331
      printf (" %lx", mask[i]);
332
  }
333
  puts ("");
334
#endif
335
 
336
  class->gc_object_type = (void *) GC_make_descriptor (mask, bits_no);
337
}
338
 
339
 
340
/* Returns YES if type denotes a pointer type, NO otherwise */
341
static inline BOOL
342
__objc_ivar_pointer (const char *type)
343
{
344
  type = objc_skip_type_qualifiers (type);
345
 
346
  return (*type == _C_ID
347
          || *type == _C_CLASS
348
          || *type == _C_SEL
349
          || *type == _C_PTR
350
          || *type == _C_CHARPTR
351
          || *type == _C_ATOM);
352
}
353
 
354
 
355
/* Mark the instance variable whose name is given by ivarname as a
356
   weak pointer (a pointer hidden to the garbage collector) if
357
   gc_invisible is true. If gc_invisible is false it unmarks the
358
   instance variable and makes it a normal pointer, visible to the
359
   garbage collector.
360
 
361
   This operation only makes sense on instance variables that are
362
   pointers.  */
363
void
364
class_ivar_set_gcinvisible (Class class, const char *ivarname,
365
                            BOOL gc_invisible)
366
{
367
  int i, ivar_count;
368
  struct objc_ivar_list *ivars;
369
 
370
  if (! class || ! ivarname)
371
    return;
372
 
373
  ivars = class->ivars;
374
  if (! ivars)
375
    return;
376
 
377
  ivar_count = ivars->ivar_count;
378
 
379
  for (i = 0; i < ivar_count; i++)
380
    {
381
      struct objc_ivar *ivar = &(ivars->ivar_list[i]);
382
      const char *type;
383
 
384
      if (! ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
385
        continue;
386
 
387
      assert (ivar->ivar_type);
388
      type = ivar->ivar_type;
389
 
390
      /* Skip the variable name */
391
      if (*type == '"')
392
        {
393
          for (type++; *type++ != '"';)
394
            /* do nothing */;
395
        }
396
 
397
      if (*type == _C_GCINVISIBLE)
398
        {
399
          char *new_type;
400
 
401
          if (gc_invisible || ! __objc_ivar_pointer (type))
402
            return;     /* The type of the variable already matches the
403
                           requested gc_invisible type */
404
 
405
          /* The variable is gc_invisible and we have to reverse it */
406
          new_type = objc_atomic_malloc (strlen (ivar->ivar_type));
407
          strncpy (new_type, ivar->ivar_type,
408
                   (size_t)(type - ivar->ivar_type));
409
          strcat (new_type, type + 1);
410
          ivar->ivar_type = new_type;
411
        }
412
      else
413
        {
414
          char *new_type;
415
 
416
          if (! gc_invisible || ! __objc_ivar_pointer (type))
417
            return;     /* The type of the variable already matches the
418
                           requested gc_invisible type */
419
 
420
          /* The variable is gc visible and we have to make it gc_invisible */
421
          new_type = objc_malloc (strlen (ivar->ivar_type) + 2);
422
          strncpy (new_type, ivar->ivar_type,
423
                   (size_t)(type - ivar->ivar_type));
424
          strcat (new_type, "!");
425
          strcat (new_type, type);
426
          ivar->ivar_type = new_type;
427
        }
428
 
429
      __objc_generate_gc_type_description (class);
430
      return;
431
    }
432
 
433
  /* Search the instance variable in the superclasses */
434
  class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
435
}
436
 
437
#else /* !OBJC_WITH_GC */
438
 
439
void
440
__objc_generate_gc_type_description (Class class __attribute__ ((__unused__)))
441
{
442
}
443
 
444
void class_ivar_set_gcinvisible (Class class __attribute__ ((__unused__)),
445
                                 const char *ivarname __attribute__ ((__unused__)),
446
                                 BOOL gc_invisible __attribute__ ((__unused__)))
447
{
448
}
449
 
450
#endif /* OBJC_WITH_GC */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.