RSS

(root)/ildjit/iljit : 1 : src/garbage_collector_interactions.c

« back to all changes in this revision

Viewing changes to src/garbage_collector_interactions.c

Speziale Ettore
2009-11-18 13:08:01
Revision ID: ettore@mars-20091118130801-ntc9elzzzz0c62xz
Initial import into Bazaar.

Show diffs side-by-side

added added

removed removed

 
1
/*
 
2
 * Copyright (C) 2006  Campanoni Simone, Di Biagio Andrea
 
3
 *
 
4
 * iljit - This is a Just-in-time for the CIL language specified with the ECMA-335
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 */
 
20
#include <assert.h>
 
21
#include <stdlib.h>
 
22
#include <errno.h>
 
23
#include <string.h>
 
24
#include <jit/jit.h>
 
25
#include <ir_language.h>
 
26
#include <ir_method.h>
 
27
#include <jitsystem.h>
 
28
#include <compiler_memory_manager.h>
 
29
#include <gc_root_sets.h>
 
30
#include <iljit-utils.h>
 
31
 
 
32
// My headers
 
33
#include <system_manager.h>
 
34
#include <iljit.h>
 
35
#include <general_tools.h>
 
36
#include <layout_manager.h>
 
37
#include <lib_lock.h>
 
38
// End
 
39
 
 
40
/* Methods casts, used during functions link setup for convenience */
 
41
#define GCI_PRINTARRAY                                                  \
 
42
        (void           (*)(void*, char*))                              \
 
43
        gci_printArray
 
44
#define GCI_PRINTOBJECT                                                 \
 
45
        (void           (*)(void*, char*))                              \
 
46
        gci_printObject
 
47
#define GCI_COLLECT                                                     \
 
48
        (void           (*)(void))                                      \
 
49
        gci_collect
 
50
#define GCI_ISSUBTYPE                                                   \
 
51
        (JITBOOLEAN     (*)(void*, void*, ILClassID))                   \
 
52
        gci_isSubtype
 
53
#define GCI_FETCHOVERSIZEOFFSET                                         \
 
54
        (JITINT32       (*)(void*))                                     \
 
55
        gci_fetchOverSizeOffset
 
56
#define GCI_FETCHOVERSIZE                                               \
 
57
        (void*          (*)(void*))                                     \
 
58
        gci_fetchOverSize
 
59
#define GCI_UNSETSTATICFLAG                                             \
 
60
        (void           (*)(void*))                                     \
 
61
        gci_unsetStaticFlag
 
62
#define GCI_GETTYPE                                                     \
 
63
        (ILClassID      (*)(void*))                                     \
 
64
        gci_getType
 
65
#define GCI_GETTYPESIZE                                                 \
 
66
        (JITINT32       (*)(void*))                                     \
 
67
        gci_getTypeSize
 
68
#define GCI_GETBINARY                                                   \
 
69
        (void*          (*)(void*))                                     \
 
70
        gci_getBinary
 
71
#define GCI_ALLOCPERMANENTOBJECT                                        \
 
72
        (void*          (*)(void*, ILClassID, JITUINT32))               \
 
73
        gci_allocPermanentObject
 
74
#define GCI_ALLOCOBJECT                                                 \
 
75
        (void*          (*)(void*, ILClassID, JITUINT32))               \
 
76
        gci_allocObject
 
77
#define GCI_ALLOCSTATICOBJECT                                           \
 
78
        (void*          (*)(void*, ILClassID, JITUINT32))               \
 
79
        gci_allocStaticObject
 
80
#define GCI_ALLOCARRAY                                                  \
 
81
        (void*          (*)(void*, ILClassID, JITINT32, JITINT32))      \
 
82
        gci_allocArray
 
83
#define GCI_FETCHFIELDOFFSET                                            \
 
84
        (JITINT32       (*)(void*, ILFieldID))                          \
 
85
        gci_fetchFieldOffset
 
86
#define GCI_FETCHSTATICFIELDOFFSET                                      \
 
87
        (JITINT32       (*)(void*, ILFieldID))                          \
 
88
        gci_fetchStaticFieldOffset
 
89
#define GCI_FETCHVTABLEOFFSET                                           \
 
90
        (JITINT32       (*)(void))                                      \
 
91
        gci_fetchVTableOffset
 
92
#define GCI_GETFIELDTYPE                                                \
 
93
        (JITUINT32      (*)(void*, ILFieldID))                          \
 
94
        gci_getFieldType
 
95
#define GCI_GETINDEXOFVTABLE                                            \
 
96
        (JITUINT32      (*)(void*, ILMethodID))                         \
 
97
        gci_getIndexOfVTable
 
98
#define GCI_GETARRAYLENGTH                                              \
 
99
        (JITUINT32      (*)(void*))                                     \
 
100
        gci_getArrayLength
 
101
#define GCI_GETARRAYRANK                                                \
 
102
        (JITUINT16      (*)(void*))                                     \
 
103
        gci_getArrayRank
 
104
#define GCI_GETARRAYLENGTHOFFSET                                        \
 
105
        (JITINT32       (*)(void))                                      \
 
106
        gci_getArrayLengthOffset
 
107
#define GCI_GETOBJECTLAYOUTOFFSET                                       \
 
108
        (JITINT32       (*)(void))                                      \
 
109
        gci_getObjectLayoutOffset
 
110
#define GCI_GETARRAYSLOTIRTYPE                                          \
 
111
        (JITUINT32      (*)(void*))                                     \
 
112
        gci_getArraySlotIRType
 
113
#define GCI_GETVTABLE                                                   \
 
114
        (void**         (*)(void*))                                     \
 
115
        gci_getVTable
 
116
#define GCI_ISSTATIC                                                    \
 
117
        (JITBOOLEAN     (*)(void*))                                     \
 
118
        gci_isStatic
 
119
#define GCI_ISFINALIZED                                                 \
 
120
        (JITBOOLEAN     (*)(void*))                                     \
 
121
        gci_isFinalized
 
122
#define GCI_ISPERMANENT                                                 \
 
123
        (JITBOOLEAN     (*)(void*))                                     \
 
124
        gci_isPermanent
 
125
#define GCI_ISARRAY                                                     \
 
126
        (JITBOOLEAN     (*)(void*))                                     \
 
127
        gci_isArray
 
128
#define GCI_SETSTATICFLAG                                               \
 
129
        (void           (*)(void*))                                     \
 
130
        gci_setStaticFlag
 
131
#define GCI_SETPERMANENTFLAG                                            \
 
132
        (void           (*)(void*))                                     \
 
133
        gci_setPermanentFlag
 
134
#define GCI_SETFINALIZEDFLAG                                            \
 
135
        (void           (*)(void*))                                     \
 
136
        gci_setFinalizedFlag
 
137
#define GCI_UNSETPERMANENTFLAG                                          \
 
138
        (void           (*)(void*))                                     \
 
139
        gci_unsetPermanentFlag
 
140
#define GCI_ADDROOTSET                                                  \
 
141
        (void           (*)(void***, JITUINT32))                        \
 
142
        gci_addRootSet
 
143
#define GCI_POPLASTROOTSET                                              \
 
144
        (void           (*)(void))                                      \
 
145
        gci_popLastRootSet
 
146
#define GCI_THREADCREATE                                                \
 
147
        (JITINT32       (*)(pthread_t*,                                 \
 
148
                            pthread_attr_t*,                            \
 
149
                            void* (*)(void*),                           \
 
150
                            void*))                                     \
 
151
        gci_threadCreate
 
152
#define GCI_THREADEXIT                                                  \
 
153
        (void (*)(pthread_t))                                           \
 
154
        gci_threadExit
 
155
#define GCI_LOCKOBJECT                                                  \
 
156
        (JITBOOLEAN     (*)(void*, JITINT32))                           \
 
157
        gci_lockObject
 
158
#define GCI_UNLOCKOBJECT                                                \
 
159
        (void           (*)(void*))                                     \
 
160
        gci_unlockObject
 
161
#define GCI_WAITFORPULSE                                                \
 
162
        (JITBOOLEAN     (*)(void*, JITINT32))                           \
 
163
        gci_waitForPulse
 
164
#define GCI_SIGNALPULSE                                                 \
 
165
        (void           (*)(void*))                                     \
 
166
        gci_signalPulse
 
167
#define GCI_SIGNALPULSEALL                                              \
 
168
        (void           (*)(void*))                                     \
 
169
        gci_signalPulseAll
 
170
#define SIZEOBJECT                                                      \
 
171
        (JITNUINT       (*)(void*))                                     \
 
172
        sizeObject
 
173
 
 
174
/* Retrive object header. The argument is an object address in IR machine */
 
175
#define GET_OBJECT_HEADER(object) \
 
176
        ((t_objectHeader*) ((JITNUINT)object - HEADER_FIXED_SIZE))
 
177
 
 
178
/* Retrive array header. The argument is an object address in IR machine */
 
179
#define GET_ARRAY_HEADER(array) \
 
180
        ((t_arrayHeader*) ((JITNUINT)array - HEADER_FIXED_SIZE))
 
181
 
 
182
/* Check if given object header stores given flag */
 
183
#define HAS_FLAG(header, flag) \
 
184
        ((header->flags & flag) == flag)
 
185
 
 
186
/* Check if given object header stores IS_FINALIZED flag */
 
187
#define HAS_FINALIZED_FLAG(header) \
 
188
        HAS_FLAG(header, IS_FINALIZED)
 
189
 
 
190
/* Check if given object header stores IS_COLLECTABLE flag */
 
191
#define HAS_COLLECTABLE_FLAG(header) \
 
192
        HAS_FLAG(header, IS_COLLECTABLE)
 
193
 
 
194
/* Check if given object header stores IS_STATIC flag */
 
195
#define HAS_STATIC_FLAG(header) \
 
196
        HAS_FLAG(header, IS_STATIC)
 
197
 
 
198
/* Check if given object header stores IS_ARRAY flag */
 
199
#define HAS_ARRAY_FLAG(header) \
 
200
        HAS_FLAG(header, IS_ARRAY)
 
201
 
 
202
/* Check if given header stores IS_VALUETYPE flag */
 
203
#define HAS_VALUETYPE_FLAG(header) \
 
204
        HAS_FLAG(header, IS_VALUETYPE)
 
205
 
 
206
/* Check if given garbage collector plugin needs root set support */
 
207
#define GC_NEEDS_ROOTSET(garbageCollector) \
 
208
        (garbageCollector->getSupport() & ILDJIT_GCSUPPORT_ROOTSET)
 
209
 
 
210
/*
 
211
 * Return the value of the field with given layout (fieldLayout) in object. You
 
212
 * can give an additonal field offset (additionalOffset) from object base
 
213
 * address. The type parameter is field IR machine type
 
214
 */
 
215
#define GET_FIELD_VALUE(type, object, fieldLayout, additonalOffset) \
 
216
        (*((type*) object + fieldLayout->offset + additionalOffset))
 
217
 
 
218
/* Some flags that you can store on objects/arrays headers */
 
219
#define IS_ARRAY                1
 
220
#define IS_COLLECTABLE          2
 
221
#define IS_VALUETYPE            4
 
222
#define IS_STATIC               8
 
223
#define IS_FINALIZED            16
 
224
 
 
225
/* Most programs today are single thread */
 
226
#define DEFAULT_THREAD_NUMBER   1
 
227
 
 
228
/* Object header */
 
229
typedef struct {
 
230
 
 
231
        /* Virtual table pointer */
 
232
        void*                   virtualTable;
 
233
 
 
234
        /*
 
235
         * Layout info pointer. Actual type is ILLayout or ILLayoutStatic. Describe all
 
236
         * about the type of the instance
 
237
         */
 
238
        void*                   layoutInfos;
 
239
 
 
240
        /* Object flags (e.g. collectable) */
 
241
        JITUINT16               flags;
 
242
 
 
243
        /* Object overall size */
 
244
        JITUINT32               objectSize;
 
245
 
 
246
        /* Object monitor */
 
247
        ILJITMonitor            monitor;
 
248
} t_objectHeader;
 
249
 
 
250
/* Array header */
 
251
typedef struct {
 
252
        /* Virtual table pointer */
 
253
        void*                   virtualTable;
 
254
 
 
255
        /*
 
256
         * Layout info pointer. Describe all about the type of the instance. Actual
 
257
         * type is ILLayout
 
258
         */
 
259
        void*                   layoutInfos;
 
260
 
 
261
        /* Array flags (e.g. collectable) */
 
262
        JITUINT16               flags;
 
263
 
 
264
        /* Array overall size */
 
265
        JITUINT32               objectSize;
 
266
 
 
267
        /* Object monitor */
 
268
        ILJITMonitor            monitor;
 
269
 
 
270
        /* Array rank (number of rows in a pseudo matrix) */
 
271
        JITUINT16               rank;
 
272
 
 
273
        /*
 
274
         * Maximum size of arrays lenght (maximum number of columns). Here is a
 
275
         * little schema for a bidimensional array:
 
276
         *
 
277
         * 1 2 3 # #
 
278
         * 4 5 # # #
 
279
         * 6 7 8 0 0
 
280
         *
 
281
         * The matrix rank is 3. The matrix dimension is max{3, 2, 5} = 5. Sharp (#)
 
282
         * means wasted space.
 
283
         */
 
284
        JITUINT32               dimSize;
 
285
} t_arrayHeader;
 
286
 
 
287
/* Each thread stored here its root set */
 
288
static XanHashTable*    rootSets;
 
289
 
 
290
/*
 
291
 * A root set view for the garbage collector. This variable is not NULL only
 
292
 * when the garbage collector is reading/writing the root set
 
293
 */
 
294
static XanList*         rootSetList;
 
295
 
 
296
/*
 
297
 * Add given root set to global one. Abort if current garbage collector don't
 
298
 * need root set support
 
299
 */
 
300
static void             gci_addRootSet(void*** rootSet, JITUINT32 size);
 
301
 
 
302
/* Remove last added root set from root set stack */
 
303
static void             gci_popLastRootSet(void);
 
304
 
 
305
/*
 
306
 * Create a new thread. Currently this method is only a wrapper around POSIX
 
307
 * phtread_create function. See pthread_create(3) for more infos
 
308
 */
 
309
static JITINT32         gci_threadCreate(pthread_t* thread,
 
310
                                         pthread_attr_t* attr,
 
311
                                         void* (*startRoutine)(void*),
 
312
                                         void* arg);
 
313
 
 
314
/*
 
315
 * Print array. Each message is prefixed with given prefix. If array is NULL do
 
316
 * nothing. The beavior of this routine depends on the value of PRINTDEBUG
 
317
 * macro: if disabled this routine does nothing
 
318
 */
 
319
static void             gci_printArray(void* array, char* prefix);
 
320
 
 
321
/*
 
322
 * Print given object. Each message is prefixed with given prefix. The behavior
 
323
 * of this routine depends on the value of PRINTDEBUG macro: if disabled this
 
324
 * routine does nothing
 
325
 */
 
326
static void             gci_printObject(void* object, char* prefix);
 
327
 
 
328
static void             gci_collect (void);
 
329
 
 
330
/* Check if object class is subtype of given classID */
 
331
static JITBOOLEAN       gci_isSubtype(t_system* system, void* object,
 
332
                                      ILClassID classID);
 
333
 
 
334
/* Get the offset of object oversize */
 
335
static JITINT32         gci_fetchOverSizeOffset(void* object);
 
336
 
 
337
/* Return the address of given object oversize area */
 
338
static void*            gci_fetchOverSize(void* object);
 
339
 
 
340
/* Unset STATIC flag from given object */
 
341
/* TODO: use flags &= ~IS_STATIC, right? */
 
342
static void             gci_unsetStaticFlag(void* object);
 
343
 
 
344
/* Get given object IL type */
 
345
static ILClassID        gci_getType(void* object);
 
346
 
 
347
/* Get given object IL type size*/
 
348
static JITINT32         gci_getTypeSize(void * object);
 
349
 
 
350
/* Get a pointer to object binary code in memory */
 
351
static void*            gci_getBinary(void* object);
 
352
 
 
353
/* Lock given object */
 
354
static JITBOOLEAN       gci_lockObject(void* object, JITINT32 timeout);
 
355
 
 
356
/* Unlock given object */
 
357
static void             gci_unlockObject(void* object);
 
358
 
 
359
/* Wait for a pulse signal on object */
 
360
static JITBOOLEAN       gci_waitForPulse(void* object, JITINT32 timeout);
 
361
 
 
362
/* Send a pulse signal to object */
 
363
static void             gci_signalPulse(void* object);
 
364
 
 
365
/* Send a pulse all signal to object */
 
366
static void             gci_signalPulseAll(void* object);
 
367
 
 
368
/*
 
369
 * Alloc a new permanent object of given class (classID) with the specified
 
370
 * oversize (overSize). Abort if object can't be created (e.g. no avaible
 
371
 * memory)
 
372
 */
 
373
static void*            gci_allocPermanentObject(
 
374
                                t_binary_information* binaryInfo,
 
375
                                ILClassID classID,
 
376
                                JITUINT32 overSize
 
377
                        );
 
378
 
 
379
/*
 
380
 * Alloc a new object of given class (classID) with the specified oversize.
 
381
 * Abort if object can't be created
 
382
 */
 
383
static void*            gci_allocObject(t_binary_information* binaryInfo,
 
384
                                        ILClassID classID,
 
385
                                        JITUINT32 overSize);
 
386
 
 
387
/*
 
388
 * Alloc a new static object of given class (classID) with the specified
 
389
 * oversize (overSize). Abort if object can't be created
 
390
 */
 
391
static void*            gci_allocStaticObject(t_binary_information* binaryInfo,
 
392
                                              ILClassID classID,
 
393
                                              JITUINT32 overSize);
 
394
 
 
395
/*
 
396
 * Alloc a new array. Each array element has class classID. The array
 
397
 * dimensions are rank and size. Abort if array can't be allocated
 
398
 */
 
399
static void*            gci_allocArray(t_binary_information* binaryInfo,
 
400
                                       ILClassID classID,
 
401
                                       JITINT32 rank,
 
402
                                       JITINT32 size);
 
403
 
 
404
/*
 
405
 * Get the offset of the given field (fieldID) from the start address of its
 
406
 * owner
 
407
 */
 
408
/* TODO: write unit test */
 
409
static JITINT32         gci_fetchFieldOffset(t_binary_information* binaryInfo,
 
410
                                             ILFieldID fieldID);
 
411
 
 
412
/*
 
413
 * Get the offset of the given static field (fieldID) from the start address of
 
414
 * its owner
 
415
 */
 
416
static JITINT32         gci_fetchStaticFieldOffset(
 
417
                                t_binary_information* binaryInfo,
 
418
                                ILFieldID fieldID
 
419
                        );
 
420
 
 
421
/* Get virtual table offset */
 
422
static JITINT32         gci_fetchVTableOffset(void);
 
423
 
 
424
/* Get given field type */
 
425
/* TODO: write unit test */
 
426
/* TODO: write readable code to check if given field is STATIC */
 
427
static JITUINT32        gci_getFieldType(t_binary_information* binaryInfo,
 
428
                                         ILFieldID fieldID);
 
429
 
 
430
/*
 
431
 * Get the index in the virtual table of given object (binaryInfo) of the given
 
432
 * method (methodID)
 
433
 */
 
434
static JITUINT32        gci_getIndexOfVTable(t_binary_information* binaryInfo,
 
435
                                             ILMethodID methodID);
 
436
 
 
437
/* Get given array length */
 
438
static JITUINT32        gci_getArrayLength(void* array);
 
439
 
 
440
/* Get given array rank */
 
441
static JITUINT16        gci_getArrayRank(void* array);
 
442
 
 
443
/* Get array header dimSize offset from a generic IR machine array address */
 
444
/* TODO: write unit test */
 
445
static JITINT32         gci_getArrayLengthOffset(void);
 
446
 
 
447
/* Get the offset to the object layout pointer inside an object */
 
448
static JITINT32         gci_getObjectLayoutOffset(void);
 
449
 
 
450
/* Get given array element IR type */
 
451
static JITUINT32        gci_getArraySlotIRType(void* array);
 
452
 
 
453
/* Get a pointer to given object virtual table */
 
454
static void**           gci_getVTable(void* object);
 
455
 
 
456
/* Check if given object is static */
 
457
static JITBOOLEAN       gci_isStatic(void* object);
 
458
 
 
459
/* Check if given object is permanent */
 
460
static JITBOOLEAN       gci_isPermanent(void* object);
 
461
 
 
462
/* Check if the finalize method has been already executed for the object in input.      */
 
463
static JITBOOLEAN       gci_isFinalized(void* object);
 
464
 
 
465
/* Set IS_STATIC flags on given object */
 
466
/* TODO: write unit test */
 
467
static void             gci_setStaticFlag(void* object);
 
468
 
 
469
/*
 
470
 * Set permanent flag on given object. Currently this function behave like
 
471
 * setStaticFlag
 
472
 */
 
473
/* TODO: write unit test */
 
474
static void             gci_setPermanentFlag(void* object);
 
475
 
 
476
static void             gci_setFinalizedFlag(void* object);
 
477
 
 
478
/*
 
479
 * Unset permanent flag on given object. Currently this function behave like
 
480
 * unsetStaticFlag
 
481
 */
 
482
/* TODO: write unit test */
 
483
/* TODO: rewrite flag operation like flags &= ~IS_PERMANENT */
 
484
static void             gci_unsetPermanentFlag(void* object);
 
485
 
 
486
/* Private function prototypes */
 
487
 
 
488
/*
 
489
 * Build a new instance of given type, with specified oversize (overSize) and
 
490
 * flags (isCollectable, isStatic). If allocation fails an OutOfMemoryException
 
491
 * is raised and the program is aborted. On successfull allocations return a
 
492
 * pointer to new allocated object. The returned object pointer is an IR
 
493
 * machine address (without object header)
 
494
 */
 
495
static void*            gci_createInstance(ILType* type, JITUINT32 overSize,
 
496
                                           JITBOOLEAN isCollectable,
 
497
                                           JITBOOLEAN isStatic);
 
498
 
 
499
/*
 
500
 * Build a new array that stores elements of given type. The array size depends
 
501
 * on given type size, rank and size parameters. Mark array collectable if
 
502
 * isCollectable is enabled. Return an IR machine array address on success. On
 
503
 * failure an OutOfMemoryException is raised and the program is aborted
 
504
 */
 
505
static void*            gci_createArray(ILType* type,
 
506
                                        JITBOOLEAN isCollectable,
 
507
                                        JITUINT32 rank,
 
508
                                        JITUINT32 size);
 
509
 
 
510
/* Print given root set contents */
 
511
static void             gci_printRootSets(t_root_sets* rootSets);
 
512
 
 
513
/* Print info about field described by currentFieldLayout in object */
 
514
static void             gci_printFieldInfo(void* object,
 
515
                                           ILFieldLayout* currentFieldLayout,
 
516
                                           char* optionalString,
 
517
                                           JITINT32 additionalOffset,
 
518
                                           JITBOOLEAN simpleOutput);
 
519
 
 
520
/* Print given object runtime values, e.g. fields values */
 
521
static void             gci_printRuntimeValues(void* object,
 
522
                                               XanList* fieldsLayout,
 
523
                                               JITBOOLEAN isArray,
 
524
                                               JITBOOLEAN simpleOutput);
 
525
/*
 
526
 * Fill referenceList with object references. Given object can be also an
 
527
 * array
 
528
 */
 
529
static void             gci_getReferences(void* object,
 
530
                                          XanList* referenceList,
 
531
                                          XanList* fieldsLayout,
 
532
                                          JITBOOLEAN isArray,
 
533
                                          JITBOOLEAN isValueType);
 
534
 
 
535
/* Run some cleanup tasks when a given thread die */
 
536
static void             gci_threadExit(pthread_t threadID);
 
537
 
 
538
/*
 
539
 * Fill referenceList with object references. Given object can be also an
 
540
 * array
 
541
 */
 
542
static void             gci_getReferences(void* object,
 
543
                                          XanList* referenceList,
 
544
                                          XanList* fieldsLayout,
 
545
                                          JITBOOLEAN isArray,
 
546
                                          JITBOOLEAN isValueType)
 
547
{
 
548
        /* Current array element, if given object is an array */
 
549
        JITUINT32       count;
 
550
 
 
551
        /* Given object header, if the object is an array */
 
552
        t_arrayHeader*  arrayHeader;
 
553
 
 
554
        /* Object layout infos */
 
555
        ILLayout*       layoutInfos;
 
556
 
 
557
        /* A IR machine type */
 
558
        JITUINT32       irType;
 
559
 
 
560
        t_system        *system;
 
561
 
 
562
        /* Given object field container */
 
563
        XanListItem*    currentField;
 
564
 
 
565
        /* Given object field layout */
 
566
        ILFieldLayout*  currentFieldLayout;
 
567
 
 
568
        /* Address of a field of given object */
 
569
        void*           fieldAddress;
 
570
 
 
571
        /* Assertions */
 
572
        assert(object != NULL);
 
573
        assert(referenceList != NULL);
 
574
        assert(fieldsLayout != NULL);
 
575
 
 
576
        PDEBUG("GC: getReferences: Start\n");
 
577
 
 
578
        /* Fetch the system             */
 
579
        system  = getSystem(NULL);
 
580
        assert(system != NULL);
 
581
 
 
582
        /* Given object is an array */
 
583
        if(isArray)
 
584
        {
 
585
                /* Retrieve the array header */
 
586
                arrayHeader = GET_ARRAY_HEADER(object);
 
587
 
 
588
                /* Retrieve array layout info */
 
589
                layoutInfos = (ILLayout*) arrayHeader->layoutInfos;
 
590
 
 
591
                /* Add all array elements to references objects */
 
592
                for(count = 0; count < arrayHeader->dimSize; count++)
 
593
                {
 
594
                        /* Array stores basic values */
 
595
                        if (isValueType) {
 
596
                                PDEBUG("current_field_layout->IRType == %d ", get_IR_type_from_ILType(getSystem(NULL)->type_checker, layoutInfos->type, getSystem(NULL)->binaries));
 
597
                                /* The stored values are references? */
 
598
                                irType = get_IR_type_from_ILType(system->type_checker, layoutInfos->type, system->binaries);
 
599
                                if(irType == IRVALUETYPE ||
 
600
                                   irType == IRTYPEDREF)
 
601
                                {
 
602
                                        fieldAddress = object +
 
603
                                                       count *
 
604
                                                       layoutInfos->typeSize;
 
605
 
 
606
                                        gci_getReferences(
 
607
                                                fieldAddress,
 
608
                                                referenceList,
 
609
                                                layoutInfos->fieldsLayout,
 
610
                                                JITFALSE, JITTRUE);
 
611
                                }
 
612
                        }
 
613
                        /* Array dont't stores basic values */
 
614
                        else
 
615
                        {
 
616
                                /* The stored values are objects? */
 
617
                                irType = get_IR_type_from_ILType(system->type_checker,
 
618
                                                layoutInfos->type, system->binaries);
 
619
                                if(irType == IROBJECT) {
 
620
                                        fieldAddress = object +
 
621
                                                       count *
 
622
                                                       sizeof(JITNUINT);
 
623
 
 
624
                                        gci_getReferences(
 
625
                                                fieldAddress,
 
626
                                                referenceList,
 
627
                                                layoutInfos->fieldsLayout,
 
628
                                                JITFALSE,
 
629
                                                JITFALSE);
 
630
                                }
 
631
                        }
 
632
                }
 
633
        }
 
634
        /* We are examing a real object */
 
635
        else {
 
636
                /* Visit each object field */
 
637
                currentField = fieldsLayout->first(fieldsLayout);
 
638
                while(currentField != NULL)
 
639
                {
 
640
                        /* Retrieve the current field layout informations */
 
641
                        currentFieldLayout = fieldsLayout->data(fieldsLayout,
 
642
                                                                currentField);
 
643
 
 
644
                        /* Current field stores a basic value */
 
645
                        if(currentFieldLayout->IRType == IRVALUETYPE)
 
646
                        {
 
647
                                /* Retrieve the fields layout for the valuetype */
 
648
                                layoutInfos =
 
649
                                        (ILLayout*) currentFieldLayout->layout;
 
650
 
 
651
                                /* Get field address */
 
652
                                fieldAddress = object +
 
653
                                               currentFieldLayout->offset;
 
654
 
 
655
                                /* Find references on current field */
 
656
                                gci_getReferences(fieldAddress, referenceList,
 
657
                                                  layoutInfos->fieldsLayout,
 
658
                                                  JITFALSE, JITTRUE);
 
659
                        }
 
660
                        /* Current field stores a reference */
 
661
                        else if(currentFieldLayout->IRType == IROBJECT)
 
662
                        {
 
663
                                fieldAddress = object + currentFieldLayout->offset;
 
664
 
 
665
                                PDEBUG("GC: getReferences:      Found a reference"
 
666
                                       "        = %p\n", fieldAddress);
 
667
 
 
668
                                /* The found reference points to something */
 
669
                                if(fieldAddress != NULL)
 
670
                                        referenceList->insert(referenceList,
 
671
                                                              fieldAddress);
 
672
                        }
 
673
 
 
674
                        /* Retrieve the next field */
 
675
                        currentField = fieldsLayout->next(fieldsLayout,
 
676
                                                          currentField);
 
677
                }
 
678
        }
 
679
 
 
680
        PDEBUG("GC: getReferences: Exit\n");
 
681
 
 
682
        /* Return */
 
683
        return;
 
684
}
 
685
 
 
686
/* Get objects referenced by given object */
 
687
XanList*                getReferencedObject(void* object)
 
688
{
 
689
        /* Given object header */
 
690
        t_objectHeader* objectHeader;
 
691
 
 
692
        /* Enabled if given object is an array */
 
693
        JITBOOLEAN      isArray;
 
694
 
 
695
        /* Enabled if given object is an array that stores basic type */
 
696
        JITBOOLEAN      isValueType;
 
697
 
 
698
        /* A list of references */
 
699
        XanList*        referenceList;
 
700
 
 
701
        /* Object layout infos */
 
702
        ILLayout*       layout;
 
703
 
 
704
        /* Object layout infos, if static */
 
705
        ILLayoutStatic* layoutStatic;
 
706
 
 
707
        /* Given object fields layout */
 
708
        XanList*        fieldsLayout;
 
709
 
 
710
        /* Assertions */
 
711
        assert(object != NULL);
 
712
        PDEBUG("GC: getReferencedObject: Start\n");
 
713
 
 
714
        /* Initialize local variables */
 
715
        isValueType     = JITFALSE;
 
716
 
 
717
        /* Create the list of instances */
 
718
        referenceList   = xanListNew(allocFunction, freeFunction, NULL);
 
719
        assert(referenceList != NULL);
 
720
        PDEBUG("GC: getReferencedObject:        Fetch the header of the object\n");
 
721
 
 
722
        /* Retrieve the pointer to the header of the object */
 
723
        objectHeader = GET_OBJECT_HEADER(object);
 
724
        assert(objectHeader != NULL);
 
725
        PDEBUG("GC: getReferencedObject:                Header          = %p\n", objectHeader);
 
726
        PDEBUG("GC: getReferencedObject:                Layout infos    = %p\n", objectHeader->layoutInfos);
 
727
 
 
728
        /* Given object is an array */
 
729
        if(HAS_ARRAY_FLAG(objectHeader)) {
 
730
                PDEBUG("GC: getReferencedObject:        The instance is an array\n");
 
731
 
 
732
                /* Set the isArray flag */
 
733
                isArray = JITTRUE;
 
734
 
 
735
                /* Array stores basic types */
 
736
                if(HAS_VALUETYPE_FLAG(objectHeader)) {
 
737
                        PDEBUG("GC: getReferencedObject:        The instance is a value type\n");
 
738
 
 
739
                        /* Set the isValueType flag */
 
740
                        isValueType = JITTRUE;
 
741
                }
 
742
        }
 
743
        /* Given object is a normal object */
 
744
        else
 
745
        {
 
746
                PDEBUG("GC: getReferencedObject:        "
 
747
                       "The instance is a normal object\n");
 
748
 
 
749
                isArray = JITFALSE;
 
750
        }
 
751
 
 
752
        /* Given object is static */
 
753
        if(HAS_STATIC_FLAG(objectHeader))
 
754
        {
 
755
                PDEBUG("GC: getReferencedObject:        "
 
756
                       "The instance is static\n");
 
757
 
 
758
                /* Retrieve the fields layout informations */
 
759
                layoutStatic = (ILLayoutStatic*) objectHeader->layoutInfos;
 
760
                fieldsLayout = layoutStatic->fieldsLayout;
 
761
        }
 
762
        /* Given object is a normal object */
 
763
        else
 
764
        {
 
765
                PDEBUG("GC: getReferencedObject:        "
 
766
                       "The instance is not static\n");
 
767
 
 
768
                /* Retrieve the fields layout informations */
 
769
                layout = (ILLayout*) objectHeader->layoutInfos;
 
770
                fieldsLayout = layout->fieldsLayout;
 
771
        }
 
772
 
 
773
        PDEBUG("GC: getReferencedObject:        Check if exist some fields of this object\n");
 
774
 
 
775
        /* Given object has some field? */
 
776
        if(fieldsLayout == NULL)
 
777
        {
 
778
                PDEBUG("GC: getReferencedObject:        No fields\n");
 
779
        }
 
780
        /* Fields found */
 
781
        else
 
782
        {
 
783
                PDEBUG("GC: getReferencedObject:                "
 
784
                       "Fields found\n");
 
785
                PDEBUG("GC: getReferencedObject:        "
 
786
                       "Retrieve the references\n");
 
787
 
 
788
                /* Retrive the references */
 
789
                gci_getReferences(object, referenceList, fieldsLayout,
 
790
                                  isArray, isValueType);
 
791
        }
 
792
 
 
793
        PDEBUG("GC: getReferencedObject: Exit\n");
 
794
 
 
795
        /* Return */
 
796
        return referenceList;
 
797
}
 
798
 
 
799
/* Check if given object is collectable */
 
800
JITBOOLEAN              isCollectable(void* object)
 
801
{
 
802
        /* Return value */
 
803
        JITBOOLEAN      collectable;
 
804
 
 
805
        /* Assertions */
 
806
        assert(object != NULL);
 
807
 
 
808
        PDEBUG("GC: isCollectable: START \n");
 
809
 
 
810
        /* Object uncollectable */
 
811
        if(gci_isStatic(object) || gci_isPermanent(object))
 
812
        {
 
813
                collectable = JITFALSE;
 
814
                PDEBUG("GC: isCollectable: END - NOT COLLECTABLE\n");
 
815
        }
 
816
        /* Object collectable */
 
817
        else
 
818
        {
 
819
                collectable = JITTRUE;
 
820
                PDEBUG("GC: isCollectable: END - COLLECTABLE \n");
 
821
        }
 
822
 
 
823
        return collectable;
 
824
}
 
825
 
 
826
/* Returns current root set */
 
827
XanList*                getRootSet(void)
 
828
{
 
829
        /* Root set slot index */
 
830
        JITUINT32                       count;
 
831
 
 
832
        /* System properties and functions */
 
833
        t_system*                       system;
 
834
 
 
835
        /* Currently running garbage collector */
 
836
        t_garbage_collector_plugin*     garbageCollector;
 
837
 
 
838
        /* System reflection manager */
 
839
        t_reflectManager*               reflectionManager;
 
840
 
 
841
        /* List of root sets */
 
842
        XanList*                        threadsRootSets;
 
843
 
 
844
        /* A root set container */
 
845
        XanListItem*                    threadRootSetItem;
 
846
 
 
847
        /* Root set of a thread */
 
848
        t_root_sets*                    threadRootSet;
 
849
 
 
850
        /* Error message buffer */
 
851
        char                            buffer[DIM_BUF];
 
852
 
 
853
        /* Object reference in the root set */
 
854
        void**                          objectReference;
 
855
 
 
856
        #ifdef PRINTDEBUG
 
857
        XanListItem                     *item;
 
858
        #endif
 
859
 
 
860
        /* Assertions  */
 
861
        assert(rootSetList == NULL);
 
862
 
 
863
        PDEBUG("GC: getRootSet: Start\n");
 
864
 
 
865
        /* Lock the root sets */
 
866
        rootSets->lock(rootSets);
 
867
 
 
868
        /* Allocate the new list */
 
869
        rootSetList = xanListNew(allocFunction, freeFunction, NULL);
 
870
 
 
871
        /* Get all we need */
 
872
        system                  = getSystem(NULL);
 
873
        garbageCollector        = system->garbage_collectors.gc.gc_plugin;
 
874
        reflectionManager       = &(system->reflectManager);
 
875
 
 
876
        /* Check if the current GC needs this kind of support */
 
877
        if(!GC_NEEDS_ROOTSET(garbageCollector))
 
878
        {
 
879
                snprintf(buffer, sizeof(buffer),
 
880
                         "ILJIT: ERROR = The garbage collector %s sayd that it "
 
881
                         "does not need the root set information, now it ask "
 
882
                         "for this information.",
 
883
                         garbageCollector->getName());
 
884
                print_err(buffer, 0);
 
885
                abort();
 
886
        }
 
887
 
 
888
        PDEBUG("GC: getRootSet:         Add the slots from the methods stack "
 
889
               "to the root set\n");
 
890
 
 
891
        /* Cycle throught all threads root sets */
 
892
        threadsRootSets = rootSets->toList(rootSets);
 
893
        threadRootSetItem = threadsRootSets->first(threadsRootSets);
 
894
        while(threadRootSetItem != NULL)
 
895
        {
 
896
                /* Retrive root set */
 
897
                threadRootSet = threadRootSetItem->data;
 
898
 
 
899
                /* Add the normal objects */
 
900
                count = 0;
 
901
                objectReference = threadRootSet->getRootSetSlot(threadRootSet, &count);
 
902
                count++;
 
903
                while(objectReference != NULL) {
 
904
 
 
905
                        /* Current reference points to something */
 
906
                        if((*objectReference) != NULL){
 
907
                                assert(rootSetList != NULL);
 
908
                                rootSetList->insert(rootSetList, objectReference);
 
909
                        }
 
910
 
 
911
                        /* Get next slot */
 
912
                        objectReference = threadRootSet->getRootSetSlot(threadRootSet, &count);
 
913
                        count++;
 
914
                }
 
915
 
 
916
                /* Fetch the next thread root set container */
 
917
                threadRootSetItem = threadsRootSets->next(threadsRootSets, threadRootSetItem);
 
918
        }
 
919
 
 
920
        /* Add the static objects */
 
921
        rootSetList->synchAppendList(rootSetList, system->staticMemoryManager->staticObjects->toSlotList(system->staticMemoryManager->staticObjects));
 
922
 
 
923
        /* Add the objects of the reflection library */
 
924
        if(reflectionManager->clrTypes != NULL){
 
925
                rootSetList->appendList(rootSetList, reflectionManager->clrTypes->toSlotList( reflectionManager->clrTypes));
 
926
        }
 
927
        if(reflectionManager->clrAssemblies != NULL){
 
928
                rootSetList->appendList(rootSetList, reflectionManager->clrAssemblies->toSlotList( reflectionManager->clrAssemblies));
 
929
        }
 
930
        if(reflectionManager->clrProperties != NULL){
 
931
                rootSetList->appendList(rootSetList, reflectionManager->clrProperties->toSlotList( reflectionManager->clrProperties));
 
932
        }
 
933
        if(reflectionManager->clrMethods != NULL){
 
934
                rootSetList->appendList(rootSetList, reflectionManager->clrMethods->toSlotList( reflectionManager->clrMethods));
 
935
        }
 
936
        if(reflectionManager->clrConstructors != NULL){
 
937
                rootSetList->appendList(rootSetList, reflectionManager->clrConstructors->toSlotList(reflectionManager->clrConstructors));
 
938
        }
 
939
        if(reflectionManager->clrFields != NULL){
 
940
                rootSetList->appendList(rootSetList, reflectionManager->clrFields->toSlotList(reflectionManager->clrFields));
 
941
        }
 
942
        if(reflectionManager->clrEvents != NULL){
 
943
                rootSetList->appendList(rootSetList, reflectionManager->clrEvents->toSlotList(reflectionManager->clrEvents));
 
944
        }
 
945
        if(reflectionManager->clrParameter != NULL){
 
946
                rootSetList->appendList(rootSetList, reflectionManager->clrParameter->toSlotList(reflectionManager->clrParameter));
 
947
        }
 
948
        if(reflectionManager->clrModule != NULL){
 
949
                rootSetList->appendList(rootSetList, reflectionManager->clrModule->toSlotList(reflectionManager->clrModule));
 
950
        }
 
951
 
 
952
 
 
953
        /* Add strings                                  */
 
954
        rootSetList->appendList(rootSetList, ((system->stringManager).usObjects)->toSlotList((system->stringManager).usObjects));
 
955
        rootSetList->appendList(rootSetList, ((system->stringManager).internHashTable)->toSlotList((system->stringManager).internHashTable));
 
956
 
 
957
        /* Add the OutOfMemory exception */
 
958
        rootSetList->insert(rootSetList, &(system->exception_system._OutOfMemoryException));
 
959
 
 
960
#ifdef PRINTDEBUG
 
961
        /* Print the root set */
 
962
        PDEBUG("GC: getRootSet:         Root set\n");
 
963
        item = rootSetList->first(rootSetList);
 
964
        while(item != NULL)
 
965
        {
 
966
                objectReference = (void**) rootSetList->data(rootSetList, item);
 
967
                PDEBUG("GC: getRootSet:                 Object  = %p    "
 
968
                       "Pointer to object = %p\n",
 
969
                       *objectReference, objectReference);
 
970
                item = rootSetList->next(rootSetList, item);
 
971
        }
 
972
#endif /* PRINTDEBUG */
 
973
 
 
974
        /* Unlock the root sets */
 
975
        rootSets->unlock(rootSets);
 
976
 
 
977
        /* Return the root set */
 
978
        return rootSetList;
 
979
}
 
980
 
 
981
/* Get given object size */
 
982
JITNUINT                sizeObject(void* object)
 
983
{
 
984
        /* Given object header */
 
985
        t_objectHeader* objectHeader;
 
986
 
 
987
        /* Given object total size */
 
988
        JITUINT32       overallSize;
 
989
 
 
990
        /* Assertions */
 
991
        assert(object != NULL);
 
992
 
 
993
        PDEBUG("GC: sizeObject: Start\n");
 
994
 
 
995
        /* Retrieve the pointer to the header of the object */
 
996
        objectHeader = GET_OBJECT_HEADER(object);
 
997
 
 
998
        /* Retrieve the overall size of the instance */
 
999
        overallSize = objectHeader->objectSize;
 
1000
 
 
1001
        /* Print the overall size */
 
1002
        PDEBUG("GC: sizeObject:         Size    = %u\n", overallSize);
 
1003
 
 
1004
        /* Return the value */
 
1005
        return overallSize;
 
1006
}
 
1007
 
 
1008
/* Print given object runtime values, e.g. fields values */
 
1009
static void             gci_printRuntimeValues(void* object,
 
1010
                                               XanList* fieldsLayout,
 
1011
                                               JITBOOLEAN isArray,
 
1012
                                               JITBOOLEAN simpleOutput)
 
1013
{
 
1014
        /* Given array header, if given object is an array */
 
1015
        t_arrayHeader*  arrayHeader;
 
1016
 
 
1017
        /* Array cell index, if given object is an array */
 
1018
        JITUINT32       count;
 
1019
 
 
1020
        /* Array cell layout, if given object is an array */
 
1021
        ILLayout*       layoutInfos;
 
1022
 
 
1023
        /* Address of a field of given object */
 
1024
        void*           fieldAddress;
 
1025
 
 
1026
        /* Given object current field container */
 
1027
        XanListItem*    currentField;
 
1028
 
 
1029
        /* Given object current field layout */
 
1030
        ILFieldLayout*  currentFieldLayout;
 
1031
 
 
1032
        /* Assertions */
 
1033
        assert(object != NULL);
 
1034
        assert(fieldsLayout != NULL);
 
1035
 
 
1036
        /* We are printing an array */
 
1037
        if(isArray) {
 
1038
                /* Retrieve the array header */
 
1039
                arrayHeader = GET_ARRAY_HEADER(object);
 
1040
 
 
1041
                if(!simpleOutput)
 
1042
                        PDEBUG("GC: printObject: ARRAY RUNTIME VALUES "
 
1043
                               "------ start ------ \n");
 
1044
 
 
1045
                /* Array stores basic types */
 
1046
                if(HAS_VALUETYPE_FLAG(arrayHeader))
 
1047
                {
 
1048
                        /* Get layout infos */
 
1049
                        layoutInfos = (ILLayout*) arrayHeader->layoutInfos;
 
1050
 
 
1051
                        /*
 
1052
                         * Print array elements values (they are basic, such as
 
1053
                         * JITINT)
 
1054
                         */
 
1055
                        for(count = 0; count < arrayHeader->dimSize; count++)
 
1056
                        {
 
1057
                                if (!simpleOutput)
 
1058
                                        PDEBUG("array[%d] - VALUE : \n", count);
 
1059
 
 
1060
                                fieldAddress = object + layoutInfos->typeSize * count;
 
1061
                                gci_printRuntimeValues(fieldAddress,
 
1062
                                                       fieldsLayout,
 
1063
                                                       JITFALSE,
 
1064
                                                       JITTRUE);
 
1065
                        }
 
1066
                }
 
1067
                /* Array stores references */
 
1068
                else
 
1069
                {
 
1070
                        /* Print array element values */
 
1071
                        for(count = 0; count < arrayHeader->dimSize; count++)
 
1072
                        {
 
1073
                                fieldAddress = object + count * sizeof(JITNUINT);
 
1074
                                PDEBUG("array[%d] - VALUE : %p\n", count,
 
1075
                                       (void*) *((JITNUINT*) fieldAddress));
 
1076
                        }
 
1077
                }
 
1078
        }
 
1079
        /* We are printing a normal object */
 
1080
        else
 
1081
        {
 
1082
                if (!simpleOutput)
 
1083
                        PDEBUG("GC: printObject: RUNTIME VALUES "
 
1084
                               "------ start ------ \n");
 
1085
 
 
1086
                /* Print object fields */
 
1087
                currentField = fieldsLayout->first(fieldsLayout);
 
1088
                while (currentField != NULL) {
 
1089
                        /* Retrieve the current field layout informations */
 
1090
                        currentFieldLayout = fieldsLayout->data(fieldsLayout,
 
1091
                                                                currentField);
 
1092
 
 
1093
                        /* Print the infos about the value of the current field */
 
1094
                        gci_printFieldInfo(object, currentFieldLayout, NULL,
 
1095
                                           0, JITFALSE);
 
1096
 
 
1097
                        /* Retrieve the next field */
 
1098
                        currentField = fieldsLayout->next(fieldsLayout, currentField);
 
1099
                }
 
1100
 
 
1101
        }
 
1102
 
 
1103
        if (!simpleOutput)
 
1104
                PDEBUG("GC: printObject: RUNTIME VALUES ------ end ------ \n");
 
1105
}
 
1106
 
 
1107
/* Unset permanent flag from given object */
 
1108
static void             gci_unsetPermanentFlag(void* object)
 
1109
{
 
1110
        t_objectHeader     *objectHeader;
 
1111
 
 
1112
        /* Assertions */
 
1113
        assert(object != NULL);
 
1114
 
 
1115
        /* Retrieve the pointer to the header of the object */
 
1116
        objectHeader = GET_OBJECT_HEADER(object);
 
1117
 
 
1118
        /* Unset the permanent flag */
 
1119
        objectHeader->flags &= (IS_ARRAY | IS_VALUETYPE | IS_STATIC);
 
1120
}
 
1121
 
 
1122
static void gci_setFinalizedFlag(void* object){
 
1123
        /* Given object header */
 
1124
        t_objectHeader     *objectHeader;
 
1125
 
 
1126
        /* Check pointer */
 
1127
        assert(object != NULL);
 
1128
 
 
1129
        /* Retrieve the pointer to the header of the object */
 
1130
        objectHeader = GET_OBJECT_HEADER(object);
 
1131
 
 
1132
        /* Set the static flag */
 
1133
        objectHeader->flags |= IS_FINALIZED;
 
1134
}
 
1135
 
 
1136
/* Set permanent flag on given object */
 
1137
static void     gci_setPermanentFlag(void* object)
 
1138
{
 
1139
        /* Given object header */
 
1140
        t_objectHeader     *objectHeader;
 
1141
 
 
1142
        /* Check pointer */
 
1143
        assert(object != NULL);
 
1144
 
 
1145
        /* Retrieve the pointer to the header of the object */
 
1146
        objectHeader = GET_OBJECT_HEADER(object);
 
1147
 
 
1148
        /* Set the static flag */
 
1149
        objectHeader->flags |= IS_COLLECTABLE;
 
1150
}
 
1151
 
 
1152
/* Set IS_STATIC flag on given object */
 
1153
static void     gci_setStaticFlag(void* object)
 
1154
{
 
1155
        /* Given object header */
 
1156
        t_objectHeader* objectHeader;
 
1157
 
 
1158
        /* Check pointer */
 
1159
        assert(object != NULL);
 
1160
 
 
1161
        /* Retrieve the pointer to the header of the object */
 
1162
        objectHeader = GET_OBJECT_HEADER(object);
 
1163
 
 
1164
        /* Set the static flag */
 
1165
        objectHeader->flags |= IS_STATIC;
 
1166
}
 
1167
 
 
1168
static JITBOOLEAN       gci_isFinalized(void* object){
 
1169
        /* Given object header */
 
1170
        t_objectHeader* header;
 
1171
 
 
1172
        /* Check pointer */
 
1173
        assert(object != NULL);
 
1174
 
 
1175
        /* Get object header */
 
1176
        header = GET_OBJECT_HEADER(object);
 
1177
 
 
1178
        /* Retrieve the information */
 
1179
        return HAS_FINALIZED_FLAG(header);
 
1180
}
 
1181
 
 
1182
/* Check if an object is permanent */
 
1183
static JITBOOLEAN       gci_isPermanent(void* object)
 
1184
{
 
1185
        /* Given object header */
 
1186
        t_objectHeader* header;
 
1187
 
 
1188
        /* Check pointer */
 
1189
        assert(object != NULL);
 
1190
 
 
1191
        /* Get object header */
 
1192
        header = GET_OBJECT_HEADER(object);
 
1193
 
 
1194
        /* Retrieve the information */
 
1195
        return HAS_COLLECTABLE_FLAG(header);
 
1196
}
 
1197
 
 
1198
/* Check if given object is static */
 
1199
static JITBOOLEAN       gci_isStatic(void* object)
 
1200
{
 
1201
        /* Given object header */
 
1202
        t_objectHeader* header;
 
1203
 
 
1204
        /* Check pointer */
 
1205
        assert(object != NULL);
 
1206
 
 
1207
        /* Get object header */
 
1208
        header = GET_OBJECT_HEADER(object);
 
1209
 
 
1210
        /* Check for IS_STATIC flag */
 
1211
        return HAS_STATIC_FLAG(header);
 
1212
}
 
1213
 
 
1214
 
 
1215
/* Check if given object is an array */
 
1216
static JITBOOLEAN       gci_isArray(void* object)
 
1217
{
 
1218
        /* Given object header */
 
1219
        t_objectHeader* header;
 
1220
 
 
1221
        /* Check pointer */
 
1222
        assert(object != NULL);
 
1223
 
 
1224
        /* Get object header */
 
1225
        header = GET_OBJECT_HEADER(object);
 
1226
 
 
1227
        /* Check for IS_STATIC flag */
 
1228
        return HAS_ARRAY_FLAG(header);
 
1229
}
 
1230
 
 
1231
 
 
1232
/* Get a pointer to given object virtual table */
 
1233
static void**           gci_getVTable(void* object)
 
1234
{
 
1235
        /* Given object header */
 
1236
        t_objectHeader* objectHeader;
 
1237
 
 
1238
        /* Assertions */
 
1239
        assert(object != NULL);
 
1240
 
 
1241
        /* Get object header */
 
1242
        objectHeader = GET_OBJECT_HEADER(object);
 
1243
 
 
1244
        /* Return the pointer that address the virtual table of the object */
 
1245
        return objectHeader->virtualTable;
 
1246
}
 
1247
 
 
1248
/* Get given object binary code */
 
1249
static void*            gci_getBinary(void* object)
 
1250
{
 
1251
        /* Given object header */
 
1252
        t_objectHeader* objectHeader;
 
1253
 
 
1254
        /* Object layout infos */
 
1255
        ILLayout*       layoutInfos;
 
1256
 
 
1257
        /* Assertions */
 
1258
        assert(object != NULL);
 
1259
 
 
1260
        /* Retrieve the pointer to the header of the object */
 
1261
        objectHeader = GET_OBJECT_HEADER(object);
 
1262
 
 
1263
        /* Retrieve the pointer to the layout informations */
 
1264
        layoutInfos = objectHeader->layoutInfos;
 
1265
 
 
1266
        /* Return object binary code */
 
1267
        return layoutInfos->type->binary;
 
1268
}
 
1269
 
 
1270
/* Get the IR type of array elements */
 
1271
static JITUINT32        gci_getArraySlotIRType(void* array)
 
1272
{
 
1273
        /* Given array header */
 
1274
        t_arrayHeader*  header;
 
1275
 
 
1276
        /* Given array layout infos */
 
1277
        ILLayout*       infos;
 
1278
 
 
1279
        t_system        *system;
 
1280
 
 
1281
        /* Assertions */
 
1282
        assert(array != NULL);
 
1283
 
 
1284
        /* Fetch the system             */
 
1285
        system  = getSystem(NULL);
 
1286
        assert(system != NULL);
 
1287
 
 
1288
        /* Retrieve the array header */
 
1289
        header = GET_ARRAY_HEADER(array);
 
1290
 
 
1291
        /* Retrieve the layout infos */
 
1292
        infos = (ILLayout*) header->layoutInfos;
 
1293
 
 
1294
        /* Return the array slot type */
 
1295
        return get_IR_type_from_ILType(system->type_checker, infos->type, system->binaries);
 
1296
}
 
1297
 
 
1298
static JITINT32         gci_getObjectLayoutOffset(void) {
 
1299
        t_objectHeader  objectHeader;
 
1300
        JITNUINT        objectHeaderAddress;
 
1301
        JITNUINT        objectLayoutAddress;
 
1302
        JITINT32        offset;
 
1303
 
 
1304
        /* Compute the offset */
 
1305
        objectHeaderAddress     = (JITNUINT) &objectHeader;
 
1306
        objectLayoutAddress     = (JITNUINT) &(objectHeader.layoutInfos);
 
1307
        offset                  = objectLayoutAddress - objectHeaderAddress - HEADER_FIXED_SIZE;
 
1308
 
 
1309
        /* Return computed offset */
 
1310
        return offset;
 
1311
}
 
1312
 
 
1313
/* Get array header dimSize offset from a generic IR machine array address */
 
1314
static JITINT32         gci_getArrayLengthOffset(void)
 
1315
{
 
1316
        /* A generic array header */
 
1317
        t_arrayHeader   arrayHeader;
 
1318
 
 
1319
        /* Pointer to a generic array header */
 
1320
        JITNUINT        arrayHeaderAddress;
 
1321
 
 
1322
        /* Address of dimSize field in a generic array header */
 
1323
        JITNUINT        arrayLengthAddress;
 
1324
 
 
1325
        /* dimSize field offset */
 
1326
        JITINT32            offset;
 
1327
 
 
1328
        PDEBUG("GC: getArrayLengthOffset: Start\n");
 
1329
 
 
1330
        /* Compute the offset */
 
1331
        arrayHeaderAddress = (JITNUINT) &arrayHeader;
 
1332
        arrayLengthAddress = (JITNUINT) &(arrayHeader.dimSize);
 
1333
        offset = arrayLengthAddress - arrayHeaderAddress - HEADER_FIXED_SIZE;
 
1334
 
 
1335
        PDEBUG("GC: getArrayLengthOffset:       Array header pointer    = %p\n",
 
1336
               (void*) arrayHeaderAddress);
 
1337
        PDEBUG("GC: getArrayLengthOffset:       Array length pointer    = %p\n",
 
1338
               (void*) arrayLengthAddress);
 
1339
        PDEBUG("GC: getArrayLengthOffset:       Offset                  = %d\n",
 
1340
               offset);
 
1341
        PDEBUG("GC: getArrayLengthOffset: Exit\n");
 
1342
 
 
1343
        /* Return computed offset */
 
1344
        return offset;
 
1345
}
 
1346
 
 
1347
/* Get given array rank */
 
1348
static JITUINT16        gci_getArrayRank(void* array)
 
1349
{
 
1350
        /* Given array header */
 
1351
        t_arrayHeader*  header;
 
1352
 
 
1353
        /* Assertions */
 
1354
        assert(array != NULL);
 
1355
 
 
1356
        /* Retrieve the array header */
 
1357
        header = GET_ARRAY_HEADER(array);
 
1358
 
 
1359
        /* Return the array rank */
 
1360
        return header->rank;
 
1361
}
 
1362
 
 
1363
/* Get given array length */
 
1364
static JITUINT32        gci_getArrayLength(void* array)
 
1365
{
 
1366
        /* Given array header */
 
1367
        t_arrayHeader*  header;
 
1368
 
 
1369
        /* Check pointer */
 
1370
        assert(array != NULL);
 
1371
 
 
1372
        PDEBUG("GC: getArrayLength: Start\n");
 
1373
 
 
1374
        /* Retrieve the array header */
 
1375
        header = GET_ARRAY_HEADER(array);
 
1376
 
 
1377
        PDEBUG("GC: getArrayLength:     Array length    = %d\n", header->dimSize);
 
1378
        PDEBUG("GC: getArrayLength: Exit\n");
 
1379
 
 
1380
        /* Return the length of the array */
 
1381
        return header->dimSize;
 
1382
}
 
1383
 
 
1384
/* Get methodID index in virtual table of binaryInfo */
 
1385
static JITUINT32        gci_getIndexOfVTable(t_binary_information* binaryInfo,
 
1386
                                             ILMethodID methodID)
 
1387
{
 
1388
        /* Virtual table entry */
 
1389
        t_virtual_method*       internalVMethod;
 
1390
 
 
1391
        /* System layout manager */
 
1392
        ILLayout_manager*       layoutManager;
 
1393
 
 
1394
        /* Type of virtual table owner */
 
1395
        ILType                  ownerType;
 
1396
 
 
1397
        /* Virtual table owner metadata streams */
 
1398
        t_streams_metadata*     streams;
 
1399
 
 
1400
        /* Type definiton table */
 
1401
        t_type_def_table*       typeDefTable;
 
1402
 
 
1403
#ifdef PRINTDEBUG
 
1404
        /* Method name, used in debug */
 
1405
        char               *name;
 
1406
#endif /* PRINTDEBUG */
 
1407
 
 
1408
        /* Assertions  */
 
1409
        assert(binaryInfo != NULL);
 
1410
 
 
1411
        PDEBUG("GC: getIndexOfVTable: Start\n");
 
1412
 
 
1413
        /* Get layout manager */
 
1414
        layoutManager = getSystem(NULL)->layout_manager;
 
1415
 
 
1416
        /* Fetch the binary */
 
1417
        ownerType.binary = binaryInfo;
 
1418
 
 
1419
        /* Fetch the streams */
 
1420
        streams = &(ownerType.binary->metadata.streams_metadata);
 
1421
        typeDefTable = get_table(&(streams->not_stream.tables), TYPE_DEF_TABLE);
 
1422
 
 
1423
        /* Fetch the class where the method is stored */
 
1424
        ownerType.ID = typeDefTable->get_type_from_method(streams, methodID);
 
1425
 
 
1426
        /* Print the method name */
 
1427
#ifdef PRINTDEBUG
 
1428
        name = get_string(&(streams->string_stream), methodID->name);
 
1429
        PDEBUG("GC: getIndexOfVTable:   Method  = %s\n", name);
 
1430
#endif /* PRINTDEBUG */
 
1431
 
 
1432
        /* Fetch the method */
 
1433
        internalVMethod = layoutManager->lookupMethod(layoutManager,
 
1434
                                                      &ownerType,
 
1435
                                                      methodID);
 
1436
 
 
1437
        PDEBUG("GC: getIndexOfVTable:   Index   = %u\n",
 
1438
                internalVMethod->index);
 
1439
        PDEBUG("GC: getIndexOfVTable: Exit\n");
 
1440
 
 
1441
        /* Return method index in the virtual table */
 
1442
        return internalVMethod->index;
 
1443
}
 
1444
 
 
1445
/* Get given field type */
 
1446
static JITUINT32        gci_getFieldType(t_binary_information* binaryInfo,
 
1447
                                         ILFieldID fieldID)
 
1448
{
 
1449
        /* System layout manager */
 
1450
        ILLayout_manager*       layoutManager;
 
1451
 
 
1452
        /* Field owner type */
 
1453
        ILType                  ownerType;
 
1454
 
 
1455
        /* Field owner metadata streams */
 
1456
        t_streams_metadata*     streamsMetadata;
 
1457
 
 
1458
        /* Describe the field with given fieldID */
 
1459
        ILField                 field;
 
1460
 
 
1461
        /* Info about given field owner layout */
 
1462
        ILLayout*               layoutInfos;
 
1463
 
 
1464
        /* Info about given static field owner layout */
 
1465
        ILLayoutStatic*         staticLayoutInfos;
 
1466
 
 
1467
        /* Info about field layout */
 
1468
        ILFieldLayout*          fieldInfos;
 
1469
 
 
1470
        /* Assertions */
 
1471
        assert(binaryInfo != NULL);
 
1472
 
 
1473
        /* Get system layout manager */
 
1474
        layoutManager = getSystem(NULL)->layout_manager;
 
1475
 
 
1476
        /* Setup query parameters */
 
1477
        memset(&ownerType, 0, sizeof(ILType));
 
1478
        ownerType.binary = binaryInfo;
 
1479
        memset(&field, 0, sizeof(ILField));
 
1480
        field.ID = fieldID;
 
1481
        field.binary = binaryInfo;
 
1482
 
 
1483
        /* Fetch the type that defines this field */
 
1484
        streamsMetadata = &(ownerType.binary->metadata.streams_metadata);
 
1485
        ownerType.ID = fieldID->get_owner_Type(streamsMetadata, fieldID);
 
1486
 
 
1487
        /* The given field is STATIC */
 
1488
        if (fieldID->flags & 0x10) {
 
1489
                /* Retrive the field layout informations */
 
1490
                staticLayoutInfos = layoutManager->layoutStaticType(
 
1491
                                        layoutManager,
 
1492
                                        &ownerType);
 
1493
                fieldInfos = staticLayoutInfos->fetchStaticFieldLayout(
 
1494
                                staticLayoutInfos,
 
1495
                                &field);
 
1496
        /* The given field isn't STATIC */
 
1497
        }
 
1498
        else
 
1499
        {
 
1500
                layoutInfos = layoutManager->layoutType(layoutManager,
 
1501
                                                        &ownerType);
 
1502
                fieldInfos = layoutInfos->fetchFieldLayout(layoutInfos,
 
1503
                                                           &field);
 
1504
        }
 
1505
 
 
1506
        /* Return the IR-Type */
 
1507
        return fieldInfos->IRType;
 
1508
}
 
1509
 
 
1510
/* Get virtual table offset */
 
1511
JITINT32 gci_fetchVTableOffset(void)
 
1512
{
 
1513
        return -HEADER_FIXED_SIZE;
 
1514
}
 
1515
 
 
1516
/* Get given static field offset from its owner start address */
 
1517
static JITINT32         gci_fetchStaticFieldOffset(
 
1518
                                t_binary_information* binaryInfo,
 
1519
                                ILFieldID fieldID
 
1520
                        )
 
1521
{
 
1522
        /* System layout manager */
 
1523
        ILLayout_manager*       layoutManager;
 
1524
 
 
1525
        /* Field owner type */
 
1526
        ILType                  ownerType;
 
1527
 
 
1528
        /* Describe given field */
 
1529
        ILField                 field;
 
1530
 
 
1531
        /* Field metadata streams */
 
1532
        t_streams_metadata*     streamsMetadata;
 
1533
 
 
1534
        /* Field owner layout info */
 
1535
        ILLayoutStatic*         layoutInfos;
 
1536
 
 
1537
        /* Field layout info */
 
1538
        ILFieldLayout*          fieldInfos;
 
1539
 
 
1540
        /* Assertions */
 
1541
        assert(binaryInfo != NULL);
 
1542
 
 
1543
        /* Get system layout manager*/
 
1544
        layoutManager = getSystem(NULL)->layout_manager;
 
1545
 
 
1546
        /* Initialize variables for the query */
 
1547
        memset(&ownerType, 0, sizeof(ILType));
 
1548
        ownerType.binary = binaryInfo;
 
1549
        field.ID = fieldID;
 
1550
        field.binary = binaryInfo;
 
1551
 
 
1552
        /* Retrieve the owner of the field */
 
1553
        streamsMetadata = &(field.binary->metadata.streams_metadata);
 
1554
        ownerType.ID = (ILClassID) fieldID->get_owner_Type(streamsMetadata,
 
1555
                                                           field.ID);
 
1556
 
 
1557
        /* Retrieve the layout informations of ownerType */
 
1558
        layoutInfos = layoutManager->layoutStaticType(layoutManager,
 
1559
                                                      &ownerType);
 
1560
 
 
1561
        /* Retrieve the field layout informations */
 
1562
        fieldInfos = layoutInfos->fetchStaticFieldLayout(layoutInfos, &field);
 
1563
 
 
1564
        /* Return the offset of the field */
 
1565
        return fieldInfos->offset;
 
1566
}
 
1567
 
 
1568
/* Get given field offset from its owner start address */
 
1569
static JITINT32         gci_fetchFieldOffset(t_binary_information* binaryInfo,
 
1570
                                             ILFieldID fieldID)
 
1571
{
 
1572
        /* Layout manger */
 
1573
        ILLayout_manager*       layoutManager;
 
1574
 
 
1575
        /* The ILType of the object that owns the current field */
 
1576
        ILType                  ownerType;
 
1577
 
 
1578
        /* The field with given fieldID */
 
1579
        ILField                 field;
 
1580
 
 
1581
        /* Field metadata streams */
 
1582
        t_streams_metadata*     streamsMetadata;
 
1583
 
 
1584
        /* Information about field owner layout */
 
1585
        ILLayout*               layoutInfos;
 
1586
 
 
1587
        /* Information about field layout */
 
1588
        ILFieldLayout*          fieldInfos;
 
1589
 
 
1590
        /* Assertions */
 
1591
        assert(binaryInfo != NULL);
 
1592
 
 
1593
        /* Get system layout manager */
 
1594
        layoutManager = getSystem(NULL)->layout_manager;
 
1595
 
 
1596
        /* Initialize variables for the query */
 
1597
        memset(&ownerType, 0, sizeof(ILType));
 
1598
        ownerType.binary = binaryInfo;
 
1599
        field.ID = fieldID;
 
1600
        field.binary = binaryInfo;
 
1601
 
 
1602
        /* Retrieve the owner of the field */
 
1603
        streamsMetadata = &(field.binary->metadata.streams_metadata);
 
1604
        ownerType.ID = (ILClassID) fieldID->get_owner_Type(streamsMetadata,
 
1605
                                                           field.ID);
 
1606
 
 
1607
        /* Retrieve the layout informations of ownerType */
 
1608
        layoutInfos = layoutManager->layoutType(layoutManager, &ownerType);
 
1609
 
 
1610
#ifdef PRINTDEBUG
 
1611
        debug_print_layout_informations(layoutInfos);
 
1612
#endif
 
1613
 
 
1614
        /* Retrieve the field layout informations */
 
1615
        fieldInfos = layoutInfos->fetchFieldLayout(layoutInfos, &field);
 
1616
 
 
1617
        /* Return the offset of the field */
 
1618
        return fieldInfos->offset;
 
1619
}
 
1620
 
 
1621
/* Print info about field described by currentFieldLayout in object */
 
1622
static void             gci_printFieldInfo(void* object,
 
1623
                                           ILFieldLayout* currentFieldLayout,
 
1624
                                           char* optionalString,
 
1625
                                           JITINT32 additionalOffset,
 
1626
                                           JITBOOLEAN simpleOutput)
 
1627
{
 
1628
        /* Given field layout, if it is a VALUETYPE */
 
1629
        ILLayout*       valueTypeLayout;
 
1630
 
 
1631
        /* VALUETYPE field layout */
 
1632
        ILFieldLayout*  VTFieldLayout;
 
1633
 
 
1634
        /* VALUETYPE fields list */
 
1635
        XanList*        fieldsLayout;
 
1636
 
 
1637
        /* Current VALUETYPE field container */
 
1638
        XanListItem*    currentVTField;
 
1639
 
 
1640
        /* Assertions */
 
1641
        assert(object != NULL);
 
1642
        assert(currentFieldLayout != NULL);
 
1643
 
 
1644
        /* Retrieve the field name */
 
1645
        if(optionalString == NULL)
 
1646
                optionalString = get_name_from_fieldInfo(
 
1647
                                        currentFieldLayout->field);
 
1648
 
 
1649
        /* Print field info */
 
1650
        switch(currentFieldLayout->IRType)
 
1651
        {
 
1652
 
 
1653
        /* Integer 8 bit */
 
1654
        case IRINT8:
 
1655
                if(simpleOutput)
 
1656
                        PDEBUG("%d", GET_FIELD_VALUE(JITINT16, object,
 
1657
                                                     currentFieldLayout,
 
1658
                                                     additionalOffset)
 
1659
                              );
 
1660
                else
 
1661
                        PDEBUG("%s - VALUE : %d\n", optionalString,
 
1662
                               GET_FIELD_VALUE(JITINT16, object,
 
1663
                                               currentFieldLayout,
 
1664
                                               addtionalOffset)
 
1665
                              );
 
1666
                break;
 
1667
 
 
1668
        /* Integer 32 bit */
 
1669
        case IRINT32:
 
1670
                if(simpleOutput)
 
1671
                        PDEBUG("%d", GET_FIELD_VALUE(JITINT32, object,
 
1672
                                                     currentFieldLayout,
 
1673
                                                     additionalOffset)
 
1674
                              );
 
1675
                else
 
1676
                        PDEBUG("%s - VALUE : %d\n", optionalString,
 
1677
                               GET_FIELD_VALUE(JITINT32, object,
 
1678
                                               currentFieldLayout,
 
1679
                                               addtionalOffset)
 
1680
                              );
 
1681
                break;
 
1682
 
 
1683
        /* Integer 16 bit, also used for chars */
 
1684
        case IRINT16:
 
1685
                if(simpleOutput)
 
1686
                {
 
1687
                        if(currentFieldLayout->isChar)
 
1688
                                PDEBUG("%c", GET_FIELD_VALUE(JITINT16, object,
 
1689
                                                             currentFieldLayout,
 
1690
                                                             additionalOffset)
 
1691
                                      );
 
1692
                        else
 
1693
                                PDEBUG("%d", GET_FIELD_VALUE(JITINT16, object,
 
1694
                                                             currentFieldLayout,
 
1695
                                                             additionalOffset)
 
1696
                                      );
 
1697
                }
 
1698
                else
 
1699
                {
 
1700
                        if(currentFieldLayout->isChar)
 
1701
                                PDEBUG("%s - VALUE : %c\n", optionalString,
 
1702
                                       GET_FIELD_VALUE(JITINT16, object,
 
1703
                                                       currentFieldLayout,
 
1704
                                                       addtionalOffset)
 
1705
                                      );
 
1706
                        else
 
1707
                                PDEBUG("%s - VALUE : %d\n", optionalString,
 
1708
                                       GET_FIELD_VALUE(JITINT16, object,
 
1709
                                                       currentFieldLayout,
 
1710
                                                       addtionalOffset)
 
1711
                                      );
 
1712
                }
 
1713
                break;
 
1714
 
 
1715
        /* Integer 64 bit */
 
1716
        case IRINT64:
 
1717
                if(simpleOutput)
 
1718
                        PDEBUG("%lld", GET_FIELD_VALUE(JITINT64, object,
 
1719
                                                       currentFieldLayout,
 
1720
                                                       additionalOffset)
 
1721
                              );
 
1722
                else
 
1723
                        PDEBUG("%s - VALUE : %lld\n", optionalString,
 
1724
                               GET_FIELD_VALUE(JITINT64, object,
 
1725
                                               currentFieldLayout,
 
1726
                                               addtionalOffset)
 
1727
                              );
 
1728
                break;
 
1729
 
 
1730
        /* Integer native */
 
1731
        case IRNINT:
 
1732
                if(simpleOutput)
 
1733
                        PDEBUG("%d", GET_FIELD_VALUE(JITNINT, object,
 
1734
                                                     currentFieldLayout,
 
1735
                                                     additionalOffset)
 
1736
                              );
 
1737
                else
 
1738
                        PDEBUG("%s - VALUE : %d\n", optionalString,
 
1739
                               GET_FIELD_VALUE(JITNINT, object,
 
1740
                                               currentFieldLayout,
 
1741
                                               addtionalOffset)
 
1742
                              );
 
1743
                break;
 
1744
 
 
1745
        /* Integer Unsigned 8 bit and Integer Unsigned 16 bit */
 
1746
        case IRUINT8:
 
1747
        case IRUINT16:
 
1748
                if(simpleOutput)
 
1749
                        PDEBUG("%d", GET_FIELD_VALUE(JITUINT16, object,
 
1750
                                                     currentFieldLayout,
 
1751
                                                     additionalOffset)
 
1752
                              );
 
1753
                else
 
1754
                        PDEBUG("%s - VALUE : %d\n", optionalString,
 
1755
                               GET_FIELD_VALUE(JITUINT16, object,
 
1756
                                               currentFieldLayout,
 
1757
                                               addtionalOffset)
 
1758
                              );
 
1759
                break;
 
1760
 
 
1761
        /* Integer Unsigned 32 bit */
 
1762
        case IRUINT32:
 
1763
                if(simpleOutput)
 
1764
                        PDEBUG("%d", GET_FIELD_VALUE(JITUINT32, object,
 
1765
                                                     currentFieldLayout,
 
1766
                                                     additionalOffset)
 
1767
                              );
 
1768
                else
 
1769
                        PDEBUG("%s - VALUE : %d\n", optionalString,
 
1770
                               GET_FIELD_VALUE(JITUINT32, object,
 
1771
                                               currentFieldLayout,
 
1772
                                               addtionalOffset)
 
1773
                              );
 
1774
                break;
 
1775
 
 
1776
        /* Integer Unsigned 64 bit */
 
1777
        case IRUINT64:
 
1778
                if(simpleOutput)
 
1779
                        PDEBUG("%lld", GET_FIELD_VALUE(JITUINT64, object,
 
1780
                                                       currentFieldLayout,
 
1781
                                                       additionalOffset)
 
1782
                              );
 
1783
                else
 
1784
                        PDEBUG("%s - VALUE : %lld\n", optionalString,
 
1785
                               GET_FIELD_VALUE(JITUINT64, object,
 
1786
                                               currentFieldLayout,
 
1787
                                               addtionalOffset)
 
1788
                              );
 
1789
                break;
 
1790
 
 
1791
        /* Integer Native Unsigned */
 
1792
        case IRNUINT:
 
1793
                if(simpleOutput)
 
1794
                        PDEBUG("%d", GET_FIELD_VALUE(JITNUINT, object,
 
1795
                                                     currentFieldLayout,
 
1796
                                                     additionalOffset)
 
1797
                              );
 
1798
                else
 
1799
                        PDEBUG("%s - VALUE : %d\n", optionalString,
 
1800
                               GET_FIELD_VALUE(JITNUINT, object,
 
1801
                                               currentFieldLayout,
 
1802
                                               addtionalOffset)
 
1803
                              );
 
1804
                break;
 
1805
 
 
1806
        /* Float 32 bit */
 
1807
        case IRFLOAT32:
 
1808
                if(simpleOutput)
 
1809
                        PDEBUG("%f", GET_FIELD_VALUE(JITFLOAT32, object,
 
1810
                                                     currentFieldLayout,
 
1811
                                                     additionalOffset)
 
1812
                              );
 
1813
                else
 
1814
                        PDEBUG("%s - VALUE : %f\n", optionalString,
 
1815
                               GET_FIELD_VALUE(JITFLOAT32, object,
 
1816
                                               currentFieldLayout,
 
1817
                                               addtionalOffset)
 
1818
                              );
 
1819
                break;
 
1820
 
 
1821
        /* Float 64 bit */
 
1822
        case IRFLOAT64:
 
1823
                if(simpleOutput)
 
1824
                        PDEBUG("%f", GET_FIELD_VALUE(JITFLOAT64, object,
 
1825
                                                     currentFieldLayout,
 
1826
                                                     additionalOffset)
 
1827
                              );
 
1828
                else
 
1829
                        PDEBUG("%s - VALUE : %f\n", optionalString,
 
1830
                               GET_FIELD_VALUE(JITFLOAT64, object,
 
1831
                                               currentFieldLayout,
 
1832
                                               addtionalOffset)
 
1833
                              );
 
1834
                break;
 
1835
 
 
1836
        /* Float Native */
 
1837
        case IRNFLOAT:
 
1838
                if(simpleOutput)
 
1839
                        PDEBUG("%f", GET_FIELD_VALUE(JITNFLOAT, object,
 
1840
                                                     currentFieldLayout,
 
1841
                                                     additionalOffset)
 
1842
                              );
 
1843
                else
 
1844
                        PDEBUG("%s - VALUE : %f\n", optionalString,
 
1845
                               GET_FIELD_VALUE(JITNFLOAT, object,
 
1846
                                               currentFieldLayout,
 
1847
                                               addtionalOffset)
 
1848
                              );
 
1849
                break;
 
1850
 
 
1851
        /* Pointers and addresses */
 
1852
        case IRMPOINTER:
 
1853
        case IRUPOINTER:
 
1854
        case IRTPOINTER:
 
1855
        case IROBJECT:
 
1856
                if(simpleOutput)
 
1857
                        PDEBUG("%p", (void*) GET_FIELD_VALUE(JITNUINT, object,
 
1858
                                                             currentFieldLayout,
 
1859
                                                             additionalOffset)
 
1860
                              );
 
1861
                else
 
1862
                        PDEBUG("%s - VALUE : %p\n", optionalString,
 
1863
                               (void*) GET_FIELD_VALUE(JITNUINT, object,
 
1864
                                                       currentFieldLayout,
 
1865
                                                       addtionalOffset)
 
1866
                              );
 
1867
                break;
 
1868
 
 
1869
        /* VALUETYPE or TYPED REFerences */
 
1870
        case IRVALUETYPE:
 
1871
        case IRTYPEDREF:
 
1872
                /* Initialize the value of layout */
 
1873
                valueTypeLayout = (ILLayout*) currentFieldLayout->layout;
 
1874
 
 
1875
                PDEBUG("%s - VALUETYPE [%s]--- RUNTIME VALUES --- START \n",
 
1876
                       optionalString,
 
1877
                       get_name_from_typeInfo(valueTypeLayout->type)
 
1878
                      );
 
1879
 
 
1880
                /* Get fields layout list */
 
1881
                fieldsLayout = valueTypeLayout->fieldsLayout;
 
1882
 
 
1883
                /* Print the values of object */
 
1884
                currentVTField = fieldsLayout->first(fieldsLayout);
 
1885
                while(currentVTField != NULL)
 
1886
                {
 
1887
                        /* Retrieve the current field layout informations */
 
1888
                        VTFieldLayout = fieldsLayout->data(fieldsLayout,
 
1889
                                                           currentVTField);
 
1890
 
 
1891
                        /* Print the infos about current field value */
 
1892
                        gci_printFieldInfo(object, VTFieldLayout, NULL,
 
1893
                                           additionalOffset +
 
1894
                                           currentFieldLayout->offset,
 
1895
                                           0);
 
1896
 
 
1897
                        /* Retrieve the next field */
 
1898
                        currentVTField = fieldsLayout->next(fieldsLayout,
 
1899
                                                            currentVTField);
 
1900
                }
 
1901
                PDEBUG("%s - VALUETYPE --- RUNTIME VALUES --- END\n",
 
1902
                       optionalString);
 
1903
                break;
 
1904
 
 
1905
        /* Error: unknown field type */
 
1906
        default:
 
1907
                PDEBUG("gc_INTERACTIONS : printFieldInfo: ERROR! \n");
 
1908
                print_err("gc_INTERACTIONS : printFieldInfo: ERROR!", 0);
 
1909
                abort();
 
1910
        }
 
1911
}
 
1912
 
 
1913
static void gci_collect (void){
 
1914
        t_system        *system;
 
1915
 
 
1916
        /* Fetch the system             */
 
1917
        system  = getSystem(NULL);
 
1918
        assert(system != NULL);
 
1919
 
 
1920
        /* Run the collection           */
 
1921
        (system->garbage_collectors).gc.gc_plugin->collect();
 
1922
        
 
1923
        /* Check if the garbage         *
 
1924
         * collector has called the     *
 
1925
         * getRootSet method.           */
 
1926
        if(rootSetList != NULL) {
 
1927
                rootSetList->destroyList(rootSetList);
 
1928
                rootSetList = NULL;
 
1929
        }
 
1930
        assert(rootSetList == NULL);
 
1931
 
 
1932
        /* Return                       */
 
1933
        return ;
 
1934
}
 
1935
 
 
1936
/* Print given object via debug macro */
 
1937
static void gci_printObject (void* object, char* prefix) {
 
1938
        /* Given object header */
 
1939
        t_objectHeader* objectHeader;
 
1940
 
 
1941
        /* Given array header, if object is an array */
 
1942
        t_arrayHeader*  arrayHeader;
 
1943
 
 
1944
        /* Layout info */
 
1945
        ILLayoutStatic* staticLayout;
 
1946
        ILLayout*       layout;
 
1947
 
 
1948
        /* Layout of each object field */
 
1949
        XanList*        fieldsLayout;
 
1950
 
 
1951
        /* Enabled if we are printing an array */
 
1952
        JITBOOLEAN      isArray;
 
1953
 
 
1954
        /* Preconditions */
 
1955
        assert(prefix != NULL);
 
1956
 
 
1957
        PDEBUG("GC: printObject: %s: Start\n", prefix);
 
1958
 
 
1959
        /* Object is NULL? */
 
1960
        if (object == NULL) {
 
1961
                PDEBUG("GC: printObject: %s: Object is NULL\n", prefix);
 
1962
                PDEBUG("GC: printObject: %s: Exit\n", prefix);
 
1963
                return;
 
1964
        }
 
1965
 
 
1966
        /* Initialize the fieldsLayout list */
 
1967
        fieldsLayout    = NULL;
 
1968
 
 
1969
        /* Initialize the `isArray` local variable */
 
1970
        isArray         = JITFALSE;
 
1971
 
 
1972
        /* retrieve the pointer to the header of the object */
 
1973
        objectHeader    = GET_OBJECT_HEADER(object);
 
1974
 
 
1975
        /* Print object debug info */
 
1976
        PDEBUG("GC: printObject: %s:    Header memory address   = %p\n",
 
1977
               prefix, objectHeader);
 
1978
        PDEBUG("GC: printObject: %s:    Header size     = %d\n", prefix,
 
1979
               HEADER_FIXED_SIZE);
 
1980
        PDEBUG("GC: printObject: %s:    VTable pointer  = %p\n", prefix,
 
1981
               objectHeader->virtualTable);
 
1982
        PDEBUG("GC: printObject: %s:    Object size     = %d\n", prefix,
 
1983
               objectHeader->objectSize);
 
1984
 
 
1985
        /* Print object collectable info */
 
1986
        if(HAS_COLLECTABLE_FLAG(objectHeader)){
 
1987
                PDEBUG("GC: printObject: %s:    object is collectable \n", prefix);
 
1988
        } else {
 
1989
                PDEBUG("GC: printObject: %s:    object is NOT collectable \n", prefix);
 
1990
                if (HAS_STATIC_FLAG(objectHeader)){
 
1991
                        PDEBUG("GC: printObject: %s:    object is STATIC \n", prefix);
 
1992
                }
 
1993
        }
 
1994
 
 
1995
        /* Print additional info if the object is an array */
 
1996
        if(HAS_ARRAY_FLAG(objectHeader))
 
1997
        {
 
1998
                /* Retrive the pointer to the t_arrayHeader structure */
 
1999
                arrayHeader = (t_arrayHeader *) objectHeader;
 
2000
 
 
2001
                /* Set the `isArray` flag */
 
2002
                isArray = JITTRUE;
 
2003
 
 
2004
                PDEBUG("GC: printObject: %s:    object is an Array \n",
 
2005
                       prefix);
 
2006
 
 
2007
                /* Print additional info if array stores IS_VALUETYPE flag */
 
2008
                if (HAS_VALUETYPE_FLAG(arrayHeader))
 
2009
                        PDEBUG("GC: printObject: %s:    Array of valueTypes \n",
 
2010
                               prefix);
 
2011
 
 
2012
                /* Print array general info */
 
2013
                PDEBUG("GC: printObject: %s:    object is an Array \n",
 
2014
                       prefix);
 
2015
                PDEBUG("GC: printObject: %s:    Array rank      = %d \n",
 
2016
                       prefix, arrayHeader->rank);
 
2017
                PDEBUG("GC: printObject: %s:    Array dimSize   = %d \n",
 
2018
                       prefix, arrayHeader->dimSize);
 
2019
        }
 
2020
 
 
2021
        /* Print out all the layout informations associated with the object */
 
2022
        if(HAS_STATIC_FLAG(objectHeader))
 
2023
        {
 
2024
                /* Get layout object */
 
2025
                staticLayout = (ILLayoutStatic*) objectHeader->layoutInfos;
 
2026
 
 
2027
                /* Print debug info */
 
2028
                debug_print_layoutStatic_informations(staticLayout);
 
2029
 
 
2030
                /* Retrieve the fieldsLayout informations */
 
2031
                fieldsLayout = staticLayout->fieldsLayout;
 
2032
        }
 
2033
        /* Object haven't IS_STATIC flag */
 
2034
        else
 
2035
        {
 
2036
                /* Notifiy that we are printing an array */
 
2037
                if (isArray) {
 
2038
                        PDEBUG("GC: printObject: %s: ---- %s %s: ----\n",
 
2039
                               "EACH ELEMENT OF THE ARRAY",
 
2040
                               "HAS THESE LAYOUT INFOS", prefix);
 
2041
                }
 
2042
 
 
2043
                /* Retrive an print layout info */
 
2044
                layout = (ILLayout*) objectHeader->layoutInfos;
 
2045
                debug_print_layout_informations(layout);
 
2046
 
 
2047
                /* Retrieve the fieldsLayout informations */
 
2048
                fieldsLayout = layout->fieldsLayout;
 
2049
        }
 
2050
 
 
2051
        /* No field on current object? */
 
2052
        if (fieldsLayout == NULL) {
 
2053
                PDEBUG("GC: printObject: %s: Exit\n", prefix);
 
2054
                return;
 
2055
        }
 
2056
 
 
2057
        /* Print the runtime values */
 
2058
        gci_printRuntimeValues(object, fieldsLayout, isArray, JITFALSE);
 
2059
 
 
2060
        PDEBUG("GC: printObject: %s: Exit\n", prefix);
 
2061
}
 
2062
 
 
2063
/* Alloc a new array */
 
2064
static void*            gci_allocArray(t_binary_information* binaryInfo,
 
2065
                                       ILClassID classID,
 
2066
                                       JITINT32 rank,
 
2067
                                       JITINT32 size)
 
2068
{
 
2069
        /* Array elements type */
 
2070
        ILType  objectType;
 
2071
 
 
2072
        /* New array */
 
2073
        void*   newArray;
 
2074
 
 
2075
        /* Assertions */
 
2076
        assert(binaryInfo != NULL);
 
2077
 
 
2078
        PDEBUG("GC: allocArray: Start\n");
 
2079
        PDEBUG("GC: allocArray:         Rank    = %d \n", rank);
 
2080
        PDEBUG("GC: allocArray:         Size    = %d \n", size);
 
2081
 
 
2082
        /* Build object type */
 
2083
        memset(&objectType, 0, sizeof(ILType));
 
2084
        objectType.ID = classID;
 
2085
        objectType.binary = binaryInfo;
 
2086
 
 
2087
        /* Create a new array */
 
2088
        newArray = gci_createArray(&objectType, JITTRUE, rank, size);
 
2089
        PDEBUG("GC: allocArray:         New array       = %p\n", newArray);
 
2090
 
 
2091
        /* Return the just created array instance */
 
2092
        PDEBUG("GC: allocArray: Exit\n");
 
2093
        return newArray;
 
2094
}
 
2095
 
 
2096
/* Alloc a new static object */
 
2097
static void*            gci_allocStaticObject(t_binary_information* binaryInfo,
 
2098
                                              ILClassID classID,
 
2099
                                              JITUINT32 overSize)
 
2100
{
 
2101
        /* Object IL type description */
 
2102
        ILType              objectType;
 
2103
 
 
2104
        /* Assertions */
 
2105
        assert(binaryInfo != NULL);
 
2106
 
 
2107
        /* Build object type description */
 
2108
        memset(&objectType, 0, sizeof(ILType));
 
2109
        objectType.ID = classID;
 
2110
        objectType.binary = binaryInfo;
 
2111
 
 
2112
        /* Create a permanent new instance */
 
2113
        return gci_createInstance(&objectType, overSize, JITFALSE, JITTRUE);
 
2114
}
 
2115
 
 
2116
/* Alloc a new normal object */
 
2117
static void*            gci_allocObject(t_binary_information* binaryInfo,
 
2118
                                        ILClassID classID,
 
2119
                                        JITUINT32 overSize)
 
2120
{
 
2121
        /* New object type */
 
2122
        ILType  objectType;
 
2123
 
 
2124
        /* New instance */
 
2125
        void*   newObject;
 
2126
 
 
2127
        /* Check pointer */
 
2128
        assert(binaryInfo != NULL);
 
2129
 
 
2130
        PDEBUG("GC: allocObject: Start\n");
 
2131
        PDEBUG("GC: allocObject:        Binary = %s\n", binaryInfo->name);
 
2132
 
 
2133
        /* Make a new object type */
 
2134
        PDEBUG("GC: allocObject:        Make a new type information\n");
 
2135
        memset(&objectType, 0, sizeof(ILType));
 
2136
        objectType.ID           = classID;
 
2137
        objectType.binary       = binaryInfo;
 
2138
 
 
2139
        /* Create a new instance */
 
2140
        PDEBUG("GC: allocObject:        Create the new instance\n");
 
2141
        newObject = gci_createInstance(&objectType, overSize, JITTRUE, JITFALSE);
 
2142
        PDEBUG("GC: allocObject:        New instance is %p\n", newObject);
 
2143
 
 
2144
        /* Return the just created instance */
 
2145
        PDEBUG("GC: allocObject: Exit\n");
 
2146
        return newObject;
 
2147
}
 
2148
 
 
2149
/* Create a new permanent object */
 
2150
static void*            gci_allocPermanentObject(
 
2151
                                t_binary_information* binaryInfo,
 
2152
                                ILClassID classID,
 
2153
                                JITUINT32 overSize
 
2154
                        )
 
2155
{
 
2156
        /* Object description */
 
2157
        ILType  objectType;
 
2158
 
 
2159
        /* Assertions */
 
2160
        assert(binaryInfo != NULL);
 
2161
 
 
2162
        /* Build object description */
 
2163
        memset(&objectType, 0, sizeof(ILType));
 
2164
        objectType.ID = classID;
 
2165
        objectType.binary = binaryInfo;
 
2166
 
 
2167
        /* Try to alloc a new object */
 
2168
        return gci_createInstance(&objectType, overSize, JITFALSE, JITFALSE);
 
2169
}
 
2170
 
 
2171
/* Unset given object STATIC flag */
 
2172
static void             gci_unsetStaticFlag(void* object)
 
2173
{
 
2174
        /* Given object header */
 
2175
        t_objectHeader* objectHeader;
 
2176
 
 
2177
        /* Assertions */
 
2178
        assert(object != NULL);
 
2179
 
 
2180
        /* Retrieve the pointer to the header of the object */
 
2181
        objectHeader = GET_OBJECT_HEADER(object);
 
2182
 
 
2183
        /* Unset the static flag */
 
2184
        objectHeader->flags &= (IS_ARRAY | IS_VALUETYPE | IS_COLLECTABLE);
 
2185
}
 
2186
 
 
2187
/* Get the oversize offset of the given object */
 
2188
static JITINT32         gci_fetchOverSizeOffset(void* object)
 
2189
{
 
2190
        /* Object header */
 
2191
        t_objectHeader* objectHeader;
 
2192
 
 
2193
        /* Array header */
 
2194
        t_arrayHeader*  arrayHeader;
 
2195
 
 
2196
        /* Object/Array layout */
 
2197
        ILLayout*       layoutInfos;
 
2198
 
 
2199
        /* Object layout (static version) */
 
2200
        ILLayoutStatic* staticLayoutInfos;
 
2201
 
 
2202
        /* The oversize offset */
 
2203
        JITUINT32       oversizeOffset;
 
2204
 
 
2205
        /* Array element size */
 
2206
        JITUINT32       slotSize;
 
2207
 
 
2208
        /* Array element IR type */
 
2209
        JITUINT32       irType;
 
2210
 
 
2211
        t_system        *system;
 
2212
 
 
2213
        /* Assertions */
 
2214
        assert(object != NULL);
 
2215
 
 
2216
        /* Fetch the system     */
 
2217
        system  = getSystem(NULL);
 
2218
        assert(system != NULL);
 
2219
 
 
2220
        /* Fetch object header */
 
2221
        objectHeader = GET_OBJECT_HEADER(object);
 
2222
 
 
2223
        /* Given object is an array */
 
2224
        if(HAS_ARRAY_FLAG(objectHeader))
 
2225
        {
 
2226
                /* Retrieve the array header */
 
2227
                arrayHeader = (t_arrayHeader*) objectHeader;
 
2228
 
 
2229
                /* Retrieve the layout infos */
 
2230
                layoutInfos = (ILLayout*) arrayHeader->layoutInfos;
 
2231
 
 
2232
                /* Given array si a VALUE-TYPE? */
 
2233
                if(HAS_VALUETYPE_FLAG(arrayHeader))
 
2234
                {
 
2235
                        /* Retrieve the oversize offset */
 
2236
                        oversizeOffset = layoutInfos->typeSize *
 
2237
                                         arrayHeader->rank *
 
2238
                                         arrayHeader->dimSize;
 
2239
                /* Given array isn't a VALUE-TYPE */
 
2240
                }
 
2241
                else
 
2242
                {
 
2243
                        /* Retrieve the IR type associated with this array */
 
2244
                        irType = get_IR_type_from_ILType(system->type_checker, layoutInfos->type, system->binaries);
 
2245
 
 
2246
                        /* retrieve the slot size */
 
2247
                        slotSize = get_size_from_IRType(irType);
 
2248
 
 
2249
                        /* Evaluate the oversize offset */
 
2250
                        oversizeOffset = slotSize * arrayHeader->rank *
 
2251
                        arrayHeader->dimSize;
 
2252
                }
 
2253
        }
 
2254
        /* Given object is a real object */
 
2255
        else
 
2256
        {
 
2257
                /* Given object is STATIC */
 
2258
                if(HAS_STATIC_FLAG(objectHeader))
 
2259
                {
 
2260
                        /* Retrieve the oversize offset */
 
2261
                        staticLayoutInfos = (ILLayoutStatic*) objectHeader->layoutInfos;
 
2262
                        assert(staticLayoutInfos != NULL);
 
2263
                        oversizeOffset = staticLayoutInfos->typeSize;
 
2264
                }
 
2265
                /* Given object is a "normal" object */
 
2266
                else
 
2267
                {
 
2268
                        /* Retrive the oversize offset */
 
2269
                        layoutInfos = (ILLayout*) objectHeader->layoutInfos;
 
2270
                        assert(layoutInfos != NULL);
 
2271
                        oversizeOffset = layoutInfos->typeSize;
 
2272
                }
 
2273
        }
 
2274
 
 
2275
        /* Return the offset */
 
2276
        return oversizeOffset;
 
2277
}
 
2278
 
 
2279
/* Get object oversize area address */
 
2280
static void*            gci_fetchOverSize(void* object)
 
2281
{
 
2282
        return object + gci_fetchOverSizeOffset(object);
 
2283
}
 
2284
 
 
2285
/* Get object IL type */
 
2286
static ILClassID        gci_getType(void* object)
 
2287
{
 
2288
        /* Object header */
 
2289
        t_objectHeader* objectHeader;
 
2290
 
 
2291
        /* Object layout infos */
 
2292
        ILLayout*       layoutInfos;
 
2293
 
 
2294
        /* Assertions */
 
2295
        assert(object != NULL);
 
2296
 
 
2297
        /* Retrieve the pointer to the header of the object */
 
2298
        objectHeader = GET_OBJECT_HEADER(object);
 
2299
 
 
2300
        /* Retrieve the pointer to the layout informations */
 
2301
        layoutInfos = objectHeader->layoutInfos;
 
2302
 
 
2303
        /* Return the classID of the current object */
 
2304
        return layoutInfos->type->ID;
 
2305
}
 
2306
 
 
2307
static JITINT32 gci_getTypeSize(void * object)
 
2308
{       /* Given object type */
 
2309
        ILType                          type;
 
2310
        JITUINT32                       typeSize;
 
2311
        ILLayout*                       layoutInfos;
 
2312
        ILLayoutStatic*                 staticInfos;
 
2313
        t_system*                       system;
 
2314
        ILLayout_manager*               layoutManager;
 
2315
 
 
2316
        /* Get all we need */
 
2317
        system = getSystem(NULL);
 
2318
        layoutManager = system->layout_manager;
 
2319
 
 
2320
        /* Fetch the binary */
 
2321
        type.binary = (t_binary_information*) (system->garbage_collectors).gc.getBinary(object);
 
2322
        /* Fetch the type */
 
2323
        type.ID = (system->garbage_collectors).gc.getType(object);
 
2324
 
 
2325
 
 
2326
        /* We are creating a normal instance */
 
2327
        if(!gci_isStatic(object))
 
2328
        {       layoutInfos = layoutManager->layoutType(layoutManager, &type);
 
2329
                typeSize = layoutInfos->typeSize;
 
2330
        }
 
2331
        else
 
2332
        {       staticInfos = layoutManager->layoutStaticType(layoutManager, &type);
 
2333
                typeSize = staticInfos->typeSize;
 
2334
        }
 
2335
 
 
2336
        return typeSize;
 
2337
}
 
2338
 
 
2339
void                    setup_garbage_collector_interaction(t_system* system)
 
2340
{
 
2341
        /* printObject parameters */
 
2342
        jit_type_t                      printObjectParams[2];
 
2343
 
 
2344
        /* printArray parameters */
 
2345
        jit_type_t                      printArrayParams[2];
 
2346
 
 
2347
        /* isSubtype parameters */
 
2348
        jit_type_t                      isSubtypeParams[3];
 
2349
 
 
2350
        /* Other functions parameters */
 
2351
        jit_type_t          params[4];
 
2352
 
 
2353
        /* System garbage collector */
 
2354
        t_running_garbage_collector*    garbageCollector;
 
2355
 
 
2356
        /* Assertions */
 
2357
        assert(system != NULL);
 
2358
 
 
2359
#if INTERNAL_GC
 
2360
        /* Initialize the internal garbage collector */
 
2361
        GC_INIT();
 
2362
#endif /* INTERNAL_GC */
 
2363
 
 
2364
        /* Get garbage collector */
 
2365
        garbageCollector = &(system->garbage_collectors.gc);
 
2366
 
 
2367
        /* Make printObject signature */
 
2368
        printObjectParams[0]                    = jit_type_void_ptr;
 
2369
        printObjectParams[1]                    = jit_type_void_ptr;
 
2370
        garbageCollector->signPrintObject       = jit_type_create_signature(jit_abi_cdecl, jit_type_void, printObjectParams, 2, 0);
 
2371
 
 
2372
        /* Make printArray signature */
 
2373
        printArrayParams[0]                     = jit_type_void_ptr;
 
2374
        printArrayParams[1]                     = jit_type_void_ptr;
 
2375
        garbageCollector->signPrintArray        = jit_type_create_signature(jit_abi_cdecl, jit_type_void, printArrayParams, 2, 0);
 
2376
 
 
2377
        /* Make isSubtype signature */
 
2378
        isSubtypeParams[0] = jit_type_void_ptr;
 
2379
        isSubtypeParams[1] = jit_type_void_ptr;
 
2380
        isSubtypeParams[2] = jit_type_void_ptr;
 
2381
        garbageCollector->signIsSubtype =
 
2382
                jit_type_create_signature(jit_abi_cdecl, jit_type_short,
 
2383
                                          isSubtypeParams, 3, 0);
 
2384
 
 
2385
        /* Create allocObject signature */
 
2386
        params[0] = jit_type_void_ptr;
 
2387
        params[1] = jit_type_void_ptr;
 
2388
        params[2] = jit_type_uint;
 
2389
        garbageCollector->signAllocObject =
 
2390
                jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr,
 
2391
                                          params, 3, 0);
 
2392
 
 
2393
        /* Create the allocPermanentObject signature */
 
2394
        garbageCollector->signAllocPermanentObject =
 
2395
                garbageCollector->signAllocObject;
 
2396
 
 
2397
        /* Create allocArray signature */
 
2398
        params[0] = jit_type_void_ptr;
 
2399
        params[1] = jit_type_void_ptr;
 
2400
        params[2] = jit_type_int;
 
2401
        params[3] = jit_type_int;
 
2402
        garbageCollector->signAllocArray =
 
2403
                jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr,
 
2404
                                          params, 4, 0);
 
2405
 
 
2406
        /* Create the allocStaticObject signature */
 
2407
        garbageCollector->signAllocStaticObject =
 
2408
                garbageCollector->signAllocObject;
 
2409
 
 
2410
        /* Create the fetchOverSize signature */
 
2411
        params[0] = jit_type_void_ptr;
 
2412
        garbageCollector->signFetchOverSize =
 
2413
                jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr,
 
2414
                                          params, 1, 0);
 
2415
 
 
2416
        /* Create the fetchOverSizeOffset signature */
 
2417
        params[0] = jit_type_void_ptr;
 
2418
        garbageCollector->signFetchOverSizeOffset =
 
2419
                jit_type_create_signature(jit_abi_cdecl, jit_type_int, params,
 
2420
                                          1, 0);
 
2421
 
 
2422
        /* Create the getType signature */
 
2423
        params[0] = jit_type_void_ptr;
 
2424
        garbageCollector->signGetType =
 
2425
                jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr,
 
2426
                                          params, 1, 0);
 
2427
 
 
2428
        /* Create the unsetStaticFlag signature */
 
2429
        params[0] = jit_type_void_ptr;
 
2430
        garbageCollector->signUnsetStaticFlag =
 
2431
                jit_type_create_signature(jit_abi_cdecl, jit_type_void,
 
2432
                                          params, 1, 0);
 
2433
 
 
2434
        /* Update all the function pointers */
 
2435
        garbageCollector->printObject           = GCI_PRINTOBJECT;
 
2436
        garbageCollector->printArray            = GCI_PRINTARRAY;
 
2437
        garbageCollector->isSubtype             = GCI_ISSUBTYPE;
 
2438
        garbageCollector->fetchOverSizeOffset   = GCI_FETCHOVERSIZEOFFSET;
 
2439
        garbageCollector->fetchOverSize         = GCI_FETCHOVERSIZE;
 
2440
        garbageCollector->unsetStaticFlag       = GCI_UNSETSTATICFLAG;
 
2441
        garbageCollector->collect               = GCI_COLLECT;
 
2442
        garbageCollector->getType               = GCI_GETTYPE;
 
2443
        garbageCollector->getTypeSize = GCI_GETTYPESIZE;
 
2444
        garbageCollector->allocObject = GCI_ALLOCOBJECT;
 
2445
        garbageCollector->allocPermanentObject = GCI_ALLOCPERMANENTOBJECT;
 
2446
        garbageCollector->allocStaticObject = GCI_ALLOCSTATICOBJECT;
 
2447
        garbageCollector->allocArray = GCI_ALLOCARRAY;
 
2448
        garbageCollector->fetchFieldOffset = GCI_FETCHFIELDOFFSET;
 
2449
        garbageCollector->fetchStaticFieldOffset = GCI_FETCHSTATICFIELDOFFSET;
 
2450
        garbageCollector->fetchVTableOffset = GCI_FETCHVTABLEOFFSET;
 
2451
        garbageCollector->getFieldType = GCI_GETFIELDTYPE;
 
2452
        garbageCollector->getIndexOfVTable = GCI_GETINDEXOFVTABLE;
 
2453
        garbageCollector->getArrayLength = GCI_GETARRAYLENGTH;
 
2454
        garbageCollector->getArrayRank = GCI_GETARRAYRANK;
 
2455
        garbageCollector->getArrayLengthOffset = GCI_GETARRAYLENGTHOFFSET;
 
2456
        garbageCollector->getArraySlotIRType = GCI_GETARRAYSLOTIRTYPE;
 
2457
        garbageCollector->getBinary = GCI_GETBINARY;
 
2458
        garbageCollector->getVTable = GCI_GETVTABLE;
 
2459
        garbageCollector->addRootSet = GCI_ADDROOTSET;
 
2460
        garbageCollector->popLastRootSet = GCI_POPLASTROOTSET;
 
2461
        garbageCollector->isStatic = GCI_ISSTATIC;
 
2462
        garbageCollector->isPermanent = GCI_ISPERMANENT;
 
2463
        garbageCollector->isFinalized = GCI_ISFINALIZED;
 
2464
        garbageCollector->isArray = GCI_ISARRAY;
 
2465
        garbageCollector->setStaticFlag = GCI_SETSTATICFLAG;
 
2466
        garbageCollector->setPermanentFlag = GCI_SETPERMANENTFLAG;
 
2467
        garbageCollector->setFinalizedFlag = GCI_SETFINALIZEDFLAG;
 
2468
        garbageCollector->unsetPermanentFlag = GCI_UNSETPERMANENTFLAG;
 
2469
        garbageCollector->getSize = SIZEOBJECT;
 
2470
        garbageCollector->threadCreate = GCI_THREADCREATE;
 
2471
        garbageCollector->threadExit = GCI_THREADEXIT;
 
2472
        garbageCollector->getObjectLayoutOffset = GCI_GETOBJECTLAYOUTOFFSET;
 
2473
        garbageCollector->lockObject = GCI_LOCKOBJECT;
 
2474
        garbageCollector->unlockObject = GCI_UNLOCKOBJECT;
 
2475
        garbageCollector->waitForPulse = GCI_WAITFORPULSE;
 
2476
        garbageCollector->signalPulse = GCI_SIGNALPULSE;
 
2477
        garbageCollector->signalPulseAll = GCI_SIGNALPULSEALL;
 
2478
 
 
2479
        /* Initialize the rootSets */
 
2480
        rootSets        = NULL;
 
2481
        if(GC_NEEDS_ROOTSET(garbageCollector->gc_plugin)){
 
2482
                rootSets = xanHashTableNew(DEFAULT_THREAD_NUMBER, JITFALSE, allocFunction, dynamicReallocFunction, freeFunction, NULL, pthread_equal);
 
2483
        }
 
2484
        rootSetList     = NULL;
 
2485
 
 
2486
}
 
2487
 
 
2488
/* Create a new array that stores element of given type */
 
2489
static void*            gci_createArray(ILType* type, JITBOOLEAN isCollectable, JITUINT32 rank, JITUINT32 size) {
 
2490
        /* System info */
 
2491
        t_system*                       system;
 
2492
 
 
2493
        /* System layout manager */
 
2494
        ILLayout_manager*               layoutManager;
 
2495
 
 
2496
        /* Current garbage collector */
 
2497
        t_garbage_collector_plugin*     garbageCollector;
 
2498
 
 
2499
        /* Type analyzer */
 
2500
        t_type_analyzer*                typeAnalyzer;
 
2501
 
 
2502
        /* Array global size without oversize */
 
2503
        JITUINT32                       arraySize;
 
2504
 
 
2505
        /* Array total size */
 
2506
        JITUINT32                       overallSize;
 
2507
 
 
2508
        /* Array layout info */
 
2509
        ILLayout*                       layoutInfos;
 
2510
        ILLayout*                       arrayLayoutInfos;
 
2511
 
 
2512
        /* Pointer to new array instance */
 
2513
        void*                           array;
 
2514
 
 
2515
        /* Array element size */
 
2516
        JITUINT32                       slotSize;
 
2517
 
 
2518
        /* New instance header */
 
2519
        t_arrayHeader*                  header;
 
2520
 
 
2521
        /* Enabled if the new array contains basic types (int, long, ...) */
 
2522
        JITBOOLEAN                      isValueType;
 
2523
 
 
2524
        ILType                          arrayType;
 
2525
 
 
2526
        /* Check pointer */
 
2527
        assert(type != NULL);
 
2528
 
 
2529
        /* Get all we need */
 
2530
        system = getSystem(NULL);
 
2531
        layoutManager = system->layout_manager;
 
2532
        garbageCollector = system->garbage_collectors.gc.gc_plugin;
 
2533
        typeAnalyzer = system->type_checker->type_analyzer;
 
2534
 
 
2535
        PDEBUG("GC: createArray: START\n");
 
2536
 
 
2537
        /* Fetch the CIL type of System.Array   */
 
2538
        (system->arrayManager).fillILArrayType(&arrayType);
 
2539
        assert(arrayType.ID != NULL);
 
2540
        assert(arrayType.binary != NULL);
 
2541
 
 
2542
        /* Fetch the layout of the System.Array type    */
 
2543
        arrayLayoutInfos = layoutManager->layoutType(layoutManager, &arrayType);
 
2544
        assert(arrayLayoutInfos != NULL);
 
2545
 
 
2546
        /* Retrieve the IRType from the ILType */
 
2547
        layoutInfos = layoutManager->layoutType(layoutManager, type);
 
2548
 
 
2549
        /* Set the slot size for the array */
 
2550
        isValueType = typeAnalyzer->isValueType(typeAnalyzer, layoutInfos->type, system->binaries);
 
2551
        if(isValueType){
 
2552
                slotSize = layoutInfos->typeSize;
 
2553
        } else {
 
2554
                slotSize = get_size_from_IRType(IRMPOINTER);
 
2555
        }
 
2556
 
 
2557
        /* Set the array size */
 
2558
        arraySize = slotSize * rank * size;
 
2559
 
 
2560
        /* Retrieve the overall size */
 
2561
        overallSize = HEADER_FIXED_SIZE + arraySize + sizeof(JITNUINT);
 
2562
 
 
2563
        /*
 
2564
         * An array can't have 0 fields: set at least an oversize of
 
2565
         * sizeof(IRMPOINTER)
 
2566
         */
 
2567
        if(overallSize == HEADER_FIXED_SIZE){
 
2568
                overallSize += sizeof(IRMPOINTER);
 
2569
        }
 
2570
 
 
2571
        /* Call the garbage collector */
 
2572
        PDEBUG("GC: createArray:        slotSize == %u\n", slotSize);
 
2573
        PDEBUG("GC: createArray:        array_size == %u\n", arraySize);
 
2574
        PDEBUG("GC: createArray:        rank == %u\n", rank);
 
2575
        PDEBUG("GC: createArray:        size == %u\n", size);
 
2576
        PDEBUG("GC: createArray:        overall_size == %u\n", overallSize);
 
2577
 
 
2578
        array = garbageCollector->allocObject(overallSize);
 
2579
 
 
2580
        /* Check if the garbage collector has called the getRootSet method */
 
2581
        if(rootSetList != NULL) {
 
2582
                rootSetList->destroyList(rootSetList);
 
2583
                rootSetList = NULL;
 
2584
        }
 
2585
 
 
2586
        /* Check if the memory is finished */
 
2587
        if(array == NULL) {
 
2588
                jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
 
2589
                print_err("createArray: ERROR = Libjit does not work as "
 
2590
                          "specified.",
 
2591
                          0);
 
2592
                abort();
 
2593
        }
 
2594
 
 
2595
        /* Get array header */
 
2596
        header = (t_arrayHeader*) array;
 
2597
        assert(header != NULL);
 
2598
 
 
2599
        /* Set the IS_ARRAY flag */
 
2600
        header->flags |= IS_ARRAY;
 
2601
 
 
2602
        /* Set the IS_COLLECTABLE flag */
 
2603
        if(isCollectable){
 
2604
                header->flags |= IS_COLLECTABLE;
 
2605
        }
 
2606
 
 
2607
        /* Set the IS_VALUETYPE flag */
 
2608
        if(isValueType){
 
2609
                header->flags |= IS_VALUETYPE;
 
2610
        }
 
2611
 
 
2612
        /* Update header infos */
 
2613
        header->layoutInfos     = layoutInfos;
 
2614
        header->virtualTable    = arrayLayoutInfos->virtualTable;
 
2615
        header->objectSize      = overallSize;
 
2616
        header->rank            = rank;
 
2617
        header->dimSize         = size;
 
2618
 
 
2619
        /* Initialize object lock and condition variable */
 
2620
        ILJITMonitorInit(&header->monitor);
 
2621
 
 
2622
        PDEBUG("GC: createArray: EXIT\n");
 
2623
 
 
2624
        /* Normalize addres to IR machine format (without header) */
 
2625
        array += HEADER_FIXED_SIZE;
 
2626
        assert(array != NULL);
 
2627
 
 
2628
        /* Return the instance just created */
 
2629
        return array;
 
2630
}
 
2631
 
 
2632
/* Create a new instance of given type */
 
2633
static void*            gci_createInstance(ILType* type, JITUINT32 overSize,
 
2634
                                           JITBOOLEAN isCollectable,
 
2635
                                           JITBOOLEAN isStatic)
 
2636
{
 
2637
        /* The new instance */
 
2638
        void*                           object;
 
2639
 
 
2640
        /* The total memory we need to alloc given object */
 
2641
        JITUINT32                       overallSize;
 
2642
 
 
2643
        /* Given type basic size, without header and oversize */
 
2644
        JITUINT32                       typeSize;
 
2645
 
 
2646
        /* Given type info, if we alloc in non static mode */
 
2647
        ILLayout*                       layoutInfos;
 
2648
 
 
2649
        /* Given type info, if we alloc in static mode */
 
2650
        ILLayoutStatic*                 staticInfos;
 
2651
 
 
2652
        /* System info */
 
2653
        t_system*                       system;
 
2654
 
 
2655
        /* System layout manager */
 
2656
        ILLayout_manager*               layoutManager;
 
2657
 
 
2658
        /* Current running garbage collector */
 
2659
        t_garbage_collector_plugin*     garbageCollector;
 
2660
 
 
2661
        /* New instance header */
 
2662
        t_objectHeader*                 header;
 
2663
 
 
2664
        /* Check pointer */
 
2665
        assert(type != NULL);
 
2666
        PDEBUG("GC: createInstance: Start\n");
 
2667
 
 
2668
        /* Initialize the variables     */
 
2669
        layoutInfos             = NULL;
 
2670
        staticInfos             = NULL;
 
2671
        object                  = NULL;
 
2672
 
 
2673
        /* Get all we need */
 
2674
        system                  = getSystem(NULL);
 
2675
        layoutManager           = system->layout_manager;
 
2676
        garbageCollector        = system->garbage_collectors.gc.gc_plugin;
 
2677
        assert(system != NULL);
 
2678
        assert(layoutManager != NULL);
 
2679
        assert(garbageCollector != NULL);
 
2680
 
 
2681
        /* Retrieve the layout infos for the specified type */
 
2682
        PDEBUG("GC: createInstance:     Retrieve the layout informations\n");
 
2683
 
 
2684
        /* We are creating a normal instance */
 
2685
        if(!isStatic)
 
2686
        {
 
2687
                /* Retrieve the typeSize of the instance */
 
2688
                layoutInfos = layoutManager->layoutType(layoutManager, type);
 
2689
                PDEBUG("GC: createInstance:     Type = %s\n", get_name_from_typeInfo(type));
 
2690
                typeSize = layoutInfos->typeSize;
 
2691
        }
 
2692
        /* We are creating a static instance */
 
2693
        else
 
2694
        {
 
2695
                /* Retrieve the typeSize of the instance */
 
2696
                staticInfos = layoutManager->layoutStaticType(layoutManager,
 
2697
                                                              type);
 
2698
                typeSize = staticInfos->typeSize;
 
2699
        }
 
2700
 
 
2701
        /* Call allocObject on GC */
 
2702
        PDEBUG("GC: createInstance:     Call the GC to fetch the memory for "
 
2703
               "the new instance\n");
 
2704
 
 
2705
        overallSize = HEADER_FIXED_SIZE + typeSize + overSize;
 
2706
        object = garbageCollector->allocObject(overallSize);
 
2707
 
 
2708
        /* Check if the garbage collector has called the getRootSet method */
 
2709
        if(rootSetList != NULL) {
 
2710
                rootSetList->destroyList(rootSetList);
 
2711
                rootSetList = NULL;
 
2712
        }
 
2713
 
 
2714
        PDEBUG("GC: createInstance:     Write the header of the new object\n");
 
2715
 
 
2716
        /* Ok, the garbage collector gave us the needed memory */
 
2717
        if(object != NULL)
 
2718
        {
 
2719
                /* Erase the object memory */
 
2720
                memset(object, 0, overallSize);
 
2721
 
 
2722
                /* Get object header */
 
2723
                header = (t_objectHeader*) object;
 
2724
 
 
2725
                /* Set flags */
 
2726
                if(isCollectable)
 
2727
                        header->flags |= IS_COLLECTABLE;
 
2728
                if(isStatic)
 
2729
                        header->flags |= IS_STATIC;
 
2730
 
 
2731
                /* Save layout info, normal mode */
 
2732
                if(layoutInfos != NULL) {
 
2733
                        header->virtualTable = layoutInfos->virtualTable;
 
2734
                        header->layoutInfos = layoutInfos;
 
2735
 
 
2736
                        /* Using the default object as a matrix for the real instance */
 
2737
//                      assert(layoutInfos->initialized_obj != NULL);
 
2738
//                      memcpy(object+HEADER_FIXED_SIZE, layoutInfos->initialized_obj, typeSize);
 
2739
                }
 
2740
                /* Save static layout info into object header */
 
2741
                else {
 
2742
                        header->layoutInfos = staticInfos;
 
2743
 
 
2744
                        /* Using the default object as a matrix for the real instance */
 
2745
                        if(typeSize > 0) {
 
2746
                                assert(staticInfos->initialized_obj != NULL);
 
2747
                                memcpy(object+HEADER_FIXED_SIZE,
 
2748
                                       staticInfos->initialized_obj, typeSize);
 
2749
                        }
 
2750
                }
 
2751
                assert(header->layoutInfos != NULL);
 
2752
 
 
2753
                /* Save object size into its header */
 
2754
                header->objectSize = overallSize;
 
2755
                PDEBUG("GC: createInstance:     virtualTable = %p\n", header->virtualTable);
 
2756
                PDEBUG("GC: createInstance:     layoutInfos = %p\n", header->layoutInfos);
 
2757
                PDEBUG("GC: createInstace:      objectSize = %u\n", header->objectSize);
 
2758
 
 
2759
                /* Initialize object lock and condition variable */
 
2760
                ILJITMonitorInit(&header->monitor);
 
2761
        } else {
 
2762
 
 
2763
                /* Error: no avaible memory for allocation */
 
2764
                jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
 
2765
                print_err("createArray: ERROR = Libjit does not work as specified.", 0);
 
2766
                abort();
 
2767
        }
 
2768
 
 
2769
        /* Normalize address to IR machine format (remove header) */
 
2770
        object += HEADER_FIXED_SIZE;
 
2771
 
 
2772
        /* Return the instance just created */
 
2773
        PDEBUG("GC: createInstance: Exit\n");
 
2774
        return object;
 
2775
}
 
2776
 
 
2777
/* Print given array */
 
2778
static void             gci_printArray(void* array, char* prefix) {
 
2779
 
 
2780
        /* Check pointers */
 
2781
        assert(prefix != NULL);
 
2782
 
 
2783
        /* Try to print a NULL array? Do nothing */
 
2784
        if (array == NULL) {
 
2785
                PDEBUG("GC_INTERACTIONS: printArray: WARNING! array is NULL \n");
 
2786
                return;
 
2787
        }
 
2788
 
 
2789
        /* Print array via printObject */
 
2790
        PDEBUG("RUNTIME: printArray: %s: Start\n", prefix);
 
2791
        gci_printObject(array, prefix);
 
2792
        PDEBUG("RUNTIME: printArray: %s: Exit\n", prefix);
 
2793
}
 
2794
 
 
2795
/* Check if given object class is subtype of given class identifier */
 
2796
static JITBOOLEAN       gci_isSubtype(t_system* system, void* object,
 
2797
                                      ILClassID classID)
 
2798
{
 
2799
        /* Given object type */
 
2800
        ILType                  objectType;
 
2801
 
 
2802
        /* Garbage collector structure */
 
2803
        t_running_garbage_collector garbageCollector;
 
2804
 
 
2805
        /* Type analyzer */
 
2806
        t_type_analyzer*        typeAnalyzer;
 
2807
 
 
2808
        /* Assertions */
 
2809
        assert(classID != NULL);
 
2810
        assert(system != NULL);
 
2811
        assert(object != NULL);
 
2812
 
 
2813
        /* Initialize the variables */
 
2814
        garbageCollector = system->garbage_collectors.gc;
 
2815
        typeAnalyzer = system->type_checker->type_analyzer;
 
2816
 
 
2817
        /* Fetch the binary */
 
2818
        objectType.binary = (t_binary_information*) garbageCollector.getBinary(object);
 
2819
 
 
2820
        /* Fetch the type */
 
2821
        objectType.ID = (system->garbage_collectors).gc.getType(object);
 
2822
 
 
2823
        /* Verify if objectType is subtype of ``classID'' */
 
2824
        return typeAnalyzer->_isSubtype(typeAnalyzer, &objectType, classID, system->binaries);
 
2825
}
 
2826
 
 
2827
/* Get size of a given array slot */
 
2828
JITUINT32               getArraySlotSize(void* array)
 
2829
{
 
2830
        /* Array slot IR type */
 
2831
        JITUINT32       irType;
 
2832
 
 
2833
        /* Given array slot size */
 
2834
        JITUINT32       arraySlotSize;
 
2835
 
 
2836
        /* Given array header */
 
2837
        t_arrayHeader*  header;
 
2838
 
 
2839
        /* Array layout info */
 
2840
        ILLayout*       layoutInfos;
 
2841
 
 
2842
        /* Assertions */
 
2843
        assert(array != NULL);
 
2844
 
 
2845
#ifdef PRINTDEBUG
 
2846
        gci_printObject(array, "[ARRAY]");
 
2847
#endif /* PRINTDEBUG */
 
2848
 
 
2849
        /* Retrieve the IR type associated with the current slot type */
 
2850
        irType = gci_getArraySlotIRType(array);
 
2851
 
 
2852
        /* Array don't stores references */
 
2853
        if((irType != IRVALUETYPE) && (irType != IRTYPEDREF))
 
2854
        {
 
2855
                arraySlotSize = getIRSize(irType);
 
2856
        }
 
2857
        /* Array stores references */
 
2858
        else
 
2859
        {
 
2860
                /* Retrieve the array header */
 
2861
                header = GET_ARRAY_HEADER(array);
 
2862
 
 
2863
                /* Get layout infos */
 
2864
                layoutInfos = (ILLayout*) header->layoutInfos;
 
2865
 
 
2866
                /* Get slot size */
 
2867
                arraySlotSize = layoutInfos->typeSize;
 
2868
        }
 
2869
 
 
2870
        return arraySlotSize;
 
2871
}
 
2872
 
 
2873
/* Create a new thread */
 
2874
static JITINT32         gci_threadCreate(pthread_t* thread,
 
2875
                                         pthread_attr_t* attr,
 
2876
                                         void* (*startRoutine)(void*),
 
2877
                                         void* arg)
 
2878
{
 
2879
        return pthread_create(thread, attr, startRoutine, arg);
 
2880
}
 
2881
 
 
2882
/* Add given root set to global one */
 
2883
static void             gci_addRootSet(void*** rootSet, JITUINT32 size) {
 
2884
        /* Loop counter */
 
2885
        JITUINT32                       count;
 
2886
 
 
2887
        /* Current thread identifier */
 
2888
        pthread_t                       threadId;
 
2889
 
 
2890
        /* Current thread root set */
 
2891
        t_root_sets*                    threadRootSet;
 
2892
 
 
2893
        t_garbage_collector_plugin*     garbageCollector;
 
2894
 
 
2895
        /* Check pointer */
 
2896
        assert(rootSet != NULL);
 
2897
 
 
2898
        PDEBUG("GC: addRootSet: Start\n");
 
2899
        PDEBUG("GC: addRootSet:         Size of root set to add = %u\n", size);
 
2900
 
 
2901
        /* Get garbage collector interface */
 
2902
        garbageCollector = getSystem(NULL)->garbage_collectors.gc.gc_plugin;
 
2903
 
 
2904
        /* Check if the garbage collector has requested this kind of support */
 
2905
        if(!GC_NEEDS_ROOTSET(garbageCollector)) {
 
2906
                return;
 
2907
        }
 
2908
 
 
2909
        /* Get current thread root set */
 
2910
        threadId        = pthread_self();
 
2911
        threadRootSet   = rootSets->synchLookup(rootSets, (void *)threadId);
 
2912
 
 
2913
        /* New thread? */
 
2914
        if(threadRootSet == NULL) {
 
2915
                threadRootSet = allocFunction(sizeof(t_root_sets));
 
2916
                init_root_sets(threadRootSet);
 
2917
                rootSets->synchInsert(rootSets, threadId, threadRootSet);
 
2918
        }
 
2919
        assert(threadRootSet != NULL);
 
2920
 
 
2921
        /* Lock root set */
 
2922
        threadRootSet->lock(threadRootSet);
 
2923
 
 
2924
        /* Add a new slot for the new root set */
 
2925
        threadRootSet->addNewRootSet(threadRootSet);
 
2926
 
 
2927
        /* Add the new root set */
 
2928
        for(count = 0; count < size; count++) {
 
2929
                PDEBUG("GC: addRootSet:         Add method %u-th element\n", count);
 
2930
                assert(rootSet[count] != NULL);
 
2931
                threadRootSet->addNewRootSetSlot(threadRootSet, rootSet[count]);
 
2932
 
 
2933
                PDEBUG("GC: addRootSet:         Root set top    = %u\n", threadRootSet->top);
 
2934
        }
 
2935
        assert(threadRootSet->top > 0);
 
2936
 
 
2937
#ifdef PRINTDEBUG
 
2938
        /* Print the root sets  */
 
2939
        gci_printRootSets(threadRootSet);
 
2940
#endif /* PRINTDEBUG */
 
2941
 
 
2942
        /* Unlock root set */
 
2943
        threadRootSet->unlock(threadRootSet);
 
2944
 
 
2945
        PDEBUG("GC: addRootSet: Exit\n");
 
2946
 
 
2947
        /* Return from routine */
 
2948
        return;
 
2949
}
 
2950
 
 
2951
/* Remove last added root set from root set stack */
 
2952
static void             gci_popLastRootSet(void)
 
2953
{
 
2954
        /* Current thread root set */
 
2955
        t_root_sets*                    threadRootSet;
 
2956
        t_garbage_collector_plugin*     garbageCollector;
 
2957
 
 
2958
        PDEBUG("GC: popLastRootSet: Start\n");
 
2959
 
 
2960
        /* Fetch running garbage collector */
 
2961
        garbageCollector = getSystem(NULL)->garbage_collectors.gc.gc_plugin;
 
2962
 
 
2963
        /* Check if the garbage collector has request this kind of support      */
 
2964
        if(!GC_NEEDS_ROOTSET(garbageCollector)) {
 
2965
                return;
 
2966
        }
 
2967
 
 
2968
        /* Get current thread root set */
 
2969
        threadRootSet = rootSets->synchLookup(rootSets, pthread_self());
 
2970
        assert(threadRootSet != NULL);
 
2971
 
 
2972
        /* Lock root set */
 
2973
        threadRootSet->lock(threadRootSet);
 
2974
 
 
2975
        /* Pop the last root set */
 
2976
        threadRootSet->popLastRootSet(threadRootSet);
 
2977
 
 
2978
#ifdef PRINTDEBUG
 
2979
        /* Print the root sets */
 
2980
        gci_printRootSets(threadRootSet);
 
2981
#endif /* PRINTDEBUG */
 
2982
 
 
2983
        /* Unlock root set */
 
2984
        threadRootSet->unlock(threadRootSet);
 
2985
 
 
2986
        PDEBUG("GC: popLastRootSet: Exit\n");
 
2987
 
 
2988
        /* Return */
 
2989
        return;
 
2990
}
 
2991
 
 
2992
/* Print given root set contents */
 
2993
static void             gci_printRootSets(t_root_sets* rootSets)
 
2994
{
 
2995
        /* Loop counter */
 
2996
        JITUINT32           count;
 
2997
 
 
2998
        /* Object reference */
 
2999
        void**          objectReference;
 
3000
 
 
3001
        /* Check pointer */
 
3002
        assert(rootSets != NULL);
 
3003
 
 
3004
        PDEBUG("GC: printRootSets: Start\n");
 
3005
        PDEBUG("GC: printRootSets:      -----------------------START-----------"
 
3006
               "--------------------------------\n");
 
3007
 
 
3008
        /* Print all object references founded in the root set */
 
3009
        for(count = 0; count < rootSets->top; count++) {
 
3010
                objectReference = rootSets->getRootSetSlot(rootSets, &count);
 
3011
                if(objectReference != NULL)
 
3012
                        PDEBUG("GC: printRootSets:      "
 
3013
                               "Pointer to object       = %p    "
 
3014
                               "Object (with header)    = %p\n",
 
3015
                               objectReference,
 
3016
                               GET_OBJECT_HEADER(*objectReference));
 
3017
        }
 
3018
        PDEBUG("GC: printRootSets:      -----------------------END-------------"
 
3019
               "--------------------------------\n");
 
3020
        PDEBUG("GC: printRootSets: Exit\n");
 
3021
 
 
3022
        /* Return */
 
3023
        return;
 
3024
}
 
3025
 
 
3026
/* Remove given thread root set from the active ones */
 
3027
static void             gci_threadExit(pthread_t threadId) {
 
3028
 
 
3029
        /* The root set to delete */
 
3030
        t_root_sets* threadRootSet;
 
3031
 
 
3032
        /* Check if there is a root set         */
 
3033
        if (rootSets == NULL) return ;
 
3034
 
 
3035
        /* Lock by hand the table since we must do several operations */
 
3036
        rootSets->lock(rootSets);
 
3037
 
 
3038
        /* Search and delete given thread root set */
 
3039
        threadRootSet = rootSets->lookup(rootSets, threadId);
 
3040
        if(threadRootSet != NULL) {
 
3041
                freeFunction(threadRootSet);
 
3042
                rootSets->delete(rootSets, threadId);
 
3043
        }
 
3044
 
 
3045
        /* All its done, exit from critical section */
 
3046
        rootSets->unlock(rootSets);
 
3047
 
 
3048
}
 
3049
 
 
3050
/* Call Finalize method on given object */
 
3051
void                    callFinalizer(void* object) {
 
3052
 
 
3053
        /* Given object header */
 
3054
        t_objectHeader*         header;
 
3055
 
 
3056
        /* Given object layout infos */
 
3057
        ILLayout*               layout;
 
3058
 
 
3059
        /* The Finalize method */
 
3060
        Method                  finalize;
 
3061
 
 
3062
        /* Used to translate method */
 
3063
        TranslationPipeline*    pipeliner;
 
3064
 
 
3065
        /* Finalize arguments */
 
3066
        void*                   args[1];
 
3067
 
 
3068
        /* Finalizer aren't called on static objects */
 
3069
        header = GET_OBJECT_HEADER(object);
 
3070
        if(HAS_STATIC_FLAG(header)) return;
 
3071
        if(HAS_FINALIZED_FLAG(header)) return;
 
3072
 
 
3073
        /* Retrive Finalize method */
 
3074
        layout          = (ILLayout*) header->layoutInfos;
 
3075
        finalize        = layout->finalize;
 
3076
 
 
3077
        if (finalize != NULL){
 
3078
                        
 
3079
                /* Compile it */
 
3080
                pipeliner       = getSystem(NULL)->pipeliner;
 
3081
                pipeliner->synchInsertMethod(pipeliner, finalize, MAX_METHOD_PRIORITY);
 
3082
 
 
3083
                /* And at last run */
 
3084
                args[0] = &object;
 
3085
                jit_function_apply(finalize->getJITFunction(finalize), args, NULL);
 
3086
 
 
3087
                /* Free synchronization resources */
 
3088
                ILJITMonitorDestroy(&header->monitor);
 
3089
        }
 
3090
}
 
3091
 
 
3092
/* Lock object */
 
3093
static JITBOOLEAN gci_lockObject(void* object, JITINT32 timeout) {
 
3094
 
 
3095
        /* Object header */
 
3096
        t_objectHeader* header;
 
3097
 
 
3098
        /* Whether lock has been acquired */
 
3099
        JITBOOLEAN lockAcquired;
 
3100
 
 
3101
        /* Get object header */
 
3102
        header = GET_OBJECT_HEADER(object);
 
3103
 
 
3104
        /* Lock object */
 
3105
        lockAcquired = ILJITMonitorLock(&header->monitor, timeout);
 
3106
 
 
3107
        return lockAcquired;
 
3108
 
 
3109
}
 
3110
 
 
3111
/* Unlock object */
 
3112
static void gci_unlockObject(void* object) {
 
3113
 
 
3114
        /* Object header */
 
3115
        t_objectHeader* header;
 
3116
 
 
3117
        /* Get object header */
 
3118
        header = GET_OBJECT_HEADER(object);
 
3119
 
 
3120
        /* Unlock the object */
 
3121
        ILJITMonitorUnlock(&header->monitor);
 
3122
 
 
3123
}
 
3124
 
 
3125
/* Wait for pulse signal on object */
 
3126
static JITBOOLEAN gci_waitForPulse(void* object, JITINT32 timeout) {
 
3127
 
 
3128
        /* Object header */
 
3129
        t_objectHeader* header;
 
3130
 
 
3131
        /* Set to JITTRUE if pulse signal is detected before timeout */
 
3132
        JITBOOLEAN pulseOccursBeforeTimeout;
 
3133
 
 
3134
        /* Get object header */
 
3135
        header = GET_OBJECT_HEADER(object);
 
3136
 
 
3137
        /* Wait for signals */
 
3138
        pulseOccursBeforeTimeout = ILJITMonitorWaitForPulse(&header->monitor,
 
3139
                                                            timeout);
 
3140
 
 
3141
        return pulseOccursBeforeTimeout;
 
3142
 
 
3143
}
 
3144
 
 
3145
/* Signal pulse */
 
3146
static void gci_signalPulse(void* object) {
 
3147
 
 
3148
        /* Given object header */
 
3149
        t_objectHeader* header;
 
3150
 
 
3151
        /* Get the header */
 
3152
        header = GET_OBJECT_HEADER(object);
 
3153
 
 
3154
        /* Signal the pulse */
 
3155
        ILJITMonitorSignalPulse(&header->monitor);
 
3156
 
 
3157
}
 
3158
 
 
3159
/* Signal pulse all */
 
3160
static void gci_signalPulseAll(void* object) {
 
3161
 
 
3162
        /* Given object header */
 
3163
        t_objectHeader* header;
 
3164
 
 
3165
        /* Get the header */
 
3166
        header = GET_OBJECT_HEADER(object);
 
3167
 
 
3168
        /* Signal the pulse all */
 
3169
        ILJITMonitorSignalPulseAll(&header->monitor);
 
3170
 
 
3171
}

Loggerhead 1.17 is a web-based interface for Bazaar branches