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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libobjc/] [gc.c] - Blame information for rev 823

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

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

powered by: WebSVN 2.1.0

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