2
* Copyright (C) 2006 Campanoni Simone, Di Biagio Andrea
4
* iljit - This is a Just-in-time for the CIL language specified with the ECMA-335
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.
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.
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
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>
33
#include <system_manager.h>
35
#include <general_tools.h>
36
#include <layout_manager.h>
40
/* Methods casts, used during functions link setup for convenience */
41
#define GCI_PRINTARRAY \
42
(void (*)(void*, char*)) \
44
#define GCI_PRINTOBJECT \
45
(void (*)(void*, char*)) \
50
#define GCI_ISSUBTYPE \
51
(JITBOOLEAN (*)(void*, void*, ILClassID)) \
53
#define GCI_FETCHOVERSIZEOFFSET \
54
(JITINT32 (*)(void*)) \
55
gci_fetchOverSizeOffset
56
#define GCI_FETCHOVERSIZE \
59
#define GCI_UNSETSTATICFLAG \
63
(ILClassID (*)(void*)) \
65
#define GCI_GETTYPESIZE \
66
(JITINT32 (*)(void*)) \
68
#define GCI_GETBINARY \
71
#define GCI_ALLOCPERMANENTOBJECT \
72
(void* (*)(void*, ILClassID, JITUINT32)) \
73
gci_allocPermanentObject
74
#define GCI_ALLOCOBJECT \
75
(void* (*)(void*, ILClassID, JITUINT32)) \
77
#define GCI_ALLOCSTATICOBJECT \
78
(void* (*)(void*, ILClassID, JITUINT32)) \
80
#define GCI_ALLOCARRAY \
81
(void* (*)(void*, ILClassID, JITINT32, JITINT32)) \
83
#define GCI_FETCHFIELDOFFSET \
84
(JITINT32 (*)(void*, ILFieldID)) \
86
#define GCI_FETCHSTATICFIELDOFFSET \
87
(JITINT32 (*)(void*, ILFieldID)) \
88
gci_fetchStaticFieldOffset
89
#define GCI_FETCHVTABLEOFFSET \
90
(JITINT32 (*)(void)) \
92
#define GCI_GETFIELDTYPE \
93
(JITUINT32 (*)(void*, ILFieldID)) \
95
#define GCI_GETINDEXOFVTABLE \
96
(JITUINT32 (*)(void*, ILMethodID)) \
98
#define GCI_GETARRAYLENGTH \
99
(JITUINT32 (*)(void*)) \
101
#define GCI_GETARRAYRANK \
102
(JITUINT16 (*)(void*)) \
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*)) \
116
#define GCI_ISSTATIC \
117
(JITBOOLEAN (*)(void*)) \
119
#define GCI_ISFINALIZED \
120
(JITBOOLEAN (*)(void*)) \
122
#define GCI_ISPERMANENT \
123
(JITBOOLEAN (*)(void*)) \
125
#define GCI_ISARRAY \
126
(JITBOOLEAN (*)(void*)) \
128
#define GCI_SETSTATICFLAG \
131
#define GCI_SETPERMANENTFLAG \
134
#define GCI_SETFINALIZEDFLAG \
137
#define GCI_UNSETPERMANENTFLAG \
139
gci_unsetPermanentFlag
140
#define GCI_ADDROOTSET \
141
(void (*)(void***, JITUINT32)) \
143
#define GCI_POPLASTROOTSET \
146
#define GCI_THREADCREATE \
147
(JITINT32 (*)(pthread_t*, \
152
#define GCI_THREADEXIT \
153
(void (*)(pthread_t)) \
155
#define GCI_LOCKOBJECT \
156
(JITBOOLEAN (*)(void*, JITINT32)) \
158
#define GCI_UNLOCKOBJECT \
161
#define GCI_WAITFORPULSE \
162
(JITBOOLEAN (*)(void*, JITINT32)) \
164
#define GCI_SIGNALPULSE \
167
#define GCI_SIGNALPULSEALL \
171
(JITNUINT (*)(void*)) \
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))
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))
182
/* Check if given object header stores given flag */
183
#define HAS_FLAG(header, flag) \
184
((header->flags & flag) == flag)
186
/* Check if given object header stores IS_FINALIZED flag */
187
#define HAS_FINALIZED_FLAG(header) \
188
HAS_FLAG(header, IS_FINALIZED)
190
/* Check if given object header stores IS_COLLECTABLE flag */
191
#define HAS_COLLECTABLE_FLAG(header) \
192
HAS_FLAG(header, IS_COLLECTABLE)
194
/* Check if given object header stores IS_STATIC flag */
195
#define HAS_STATIC_FLAG(header) \
196
HAS_FLAG(header, IS_STATIC)
198
/* Check if given object header stores IS_ARRAY flag */
199
#define HAS_ARRAY_FLAG(header) \
200
HAS_FLAG(header, IS_ARRAY)
202
/* Check if given header stores IS_VALUETYPE flag */
203
#define HAS_VALUETYPE_FLAG(header) \
204
HAS_FLAG(header, IS_VALUETYPE)
206
/* Check if given garbage collector plugin needs root set support */
207
#define GC_NEEDS_ROOTSET(garbageCollector) \
208
(garbageCollector->getSupport() & ILDJIT_GCSUPPORT_ROOTSET)
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
215
#define GET_FIELD_VALUE(type, object, fieldLayout, additonalOffset) \
216
(*((type*) object + fieldLayout->offset + additionalOffset))
218
/* Some flags that you can store on objects/arrays headers */
220
#define IS_COLLECTABLE 2
221
#define IS_VALUETYPE 4
223
#define IS_FINALIZED 16
225
/* Most programs today are single thread */
226
#define DEFAULT_THREAD_NUMBER 1
231
/* Virtual table pointer */
235
* Layout info pointer. Actual type is ILLayout or ILLayoutStatic. Describe all
236
* about the type of the instance
240
/* Object flags (e.g. collectable) */
243
/* Object overall size */
244
JITUINT32 objectSize;
247
ILJITMonitor monitor;
252
/* Virtual table pointer */
256
* Layout info pointer. Describe all about the type of the instance. Actual
261
/* Array flags (e.g. collectable) */
264
/* Array overall size */
265
JITUINT32 objectSize;
268
ILJITMonitor monitor;
270
/* Array rank (number of rows in a pseudo matrix) */
274
* Maximum size of arrays lenght (maximum number of columns). Here is a
275
* little schema for a bidimensional array:
281
* The matrix rank is 3. The matrix dimension is max{3, 2, 5} = 5. Sharp (#)
282
* means wasted space.
287
/* Each thread stored here its root set */
288
static XanHashTable* rootSets;
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
294
static XanList* rootSetList;
297
* Add given root set to global one. Abort if current garbage collector don't
298
* need root set support
300
static void gci_addRootSet(void*** rootSet, JITUINT32 size);
302
/* Remove last added root set from root set stack */
303
static void gci_popLastRootSet(void);
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
309
static JITINT32 gci_threadCreate(pthread_t* thread,
310
pthread_attr_t* attr,
311
void* (*startRoutine)(void*),
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
319
static void gci_printArray(void* array, char* prefix);
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
326
static void gci_printObject(void* object, char* prefix);
328
static void gci_collect (void);
330
/* Check if object class is subtype of given classID */
331
static JITBOOLEAN gci_isSubtype(t_system* system, void* object,
334
/* Get the offset of object oversize */
335
static JITINT32 gci_fetchOverSizeOffset(void* object);
337
/* Return the address of given object oversize area */
338
static void* gci_fetchOverSize(void* object);
340
/* Unset STATIC flag from given object */
341
/* TODO: use flags &= ~IS_STATIC, right? */
342
static void gci_unsetStaticFlag(void* object);
344
/* Get given object IL type */
345
static ILClassID gci_getType(void* object);
347
/* Get given object IL type size*/
348
static JITINT32 gci_getTypeSize(void * object);
350
/* Get a pointer to object binary code in memory */
351
static void* gci_getBinary(void* object);
353
/* Lock given object */
354
static JITBOOLEAN gci_lockObject(void* object, JITINT32 timeout);
356
/* Unlock given object */
357
static void gci_unlockObject(void* object);
359
/* Wait for a pulse signal on object */
360
static JITBOOLEAN gci_waitForPulse(void* object, JITINT32 timeout);
362
/* Send a pulse signal to object */
363
static void gci_signalPulse(void* object);
365
/* Send a pulse all signal to object */
366
static void gci_signalPulseAll(void* object);
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
373
static void* gci_allocPermanentObject(
374
t_binary_information* binaryInfo,
380
* Alloc a new object of given class (classID) with the specified oversize.
381
* Abort if object can't be created
383
static void* gci_allocObject(t_binary_information* binaryInfo,
388
* Alloc a new static object of given class (classID) with the specified
389
* oversize (overSize). Abort if object can't be created
391
static void* gci_allocStaticObject(t_binary_information* binaryInfo,
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
399
static void* gci_allocArray(t_binary_information* binaryInfo,
405
* Get the offset of the given field (fieldID) from the start address of its
408
/* TODO: write unit test */
409
static JITINT32 gci_fetchFieldOffset(t_binary_information* binaryInfo,
413
* Get the offset of the given static field (fieldID) from the start address of
416
static JITINT32 gci_fetchStaticFieldOffset(
417
t_binary_information* binaryInfo,
421
/* Get virtual table offset */
422
static JITINT32 gci_fetchVTableOffset(void);
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,
431
* Get the index in the virtual table of given object (binaryInfo) of the given
434
static JITUINT32 gci_getIndexOfVTable(t_binary_information* binaryInfo,
435
ILMethodID methodID);
437
/* Get given array length */
438
static JITUINT32 gci_getArrayLength(void* array);
440
/* Get given array rank */
441
static JITUINT16 gci_getArrayRank(void* array);
443
/* Get array header dimSize offset from a generic IR machine array address */
444
/* TODO: write unit test */
445
static JITINT32 gci_getArrayLengthOffset(void);
447
/* Get the offset to the object layout pointer inside an object */
448
static JITINT32 gci_getObjectLayoutOffset(void);
450
/* Get given array element IR type */
451
static JITUINT32 gci_getArraySlotIRType(void* array);
453
/* Get a pointer to given object virtual table */
454
static void** gci_getVTable(void* object);
456
/* Check if given object is static */
457
static JITBOOLEAN gci_isStatic(void* object);
459
/* Check if given object is permanent */
460
static JITBOOLEAN gci_isPermanent(void* object);
462
/* Check if the finalize method has been already executed for the object in input. */
463
static JITBOOLEAN gci_isFinalized(void* object);
465
/* Set IS_STATIC flags on given object */
466
/* TODO: write unit test */
467
static void gci_setStaticFlag(void* object);
470
* Set permanent flag on given object. Currently this function behave like
473
/* TODO: write unit test */
474
static void gci_setPermanentFlag(void* object);
476
static void gci_setFinalizedFlag(void* object);
479
* Unset permanent flag on given object. Currently this function behave like
482
/* TODO: write unit test */
483
/* TODO: rewrite flag operation like flags &= ~IS_PERMANENT */
484
static void gci_unsetPermanentFlag(void* object);
486
/* Private function prototypes */
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)
495
static void* gci_createInstance(ILType* type, JITUINT32 overSize,
496
JITBOOLEAN isCollectable,
497
JITBOOLEAN isStatic);
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
505
static void* gci_createArray(ILType* type,
506
JITBOOLEAN isCollectable,
510
/* Print given root set contents */
511
static void gci_printRootSets(t_root_sets* rootSets);
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);
520
/* Print given object runtime values, e.g. fields values */
521
static void gci_printRuntimeValues(void* object,
522
XanList* fieldsLayout,
524
JITBOOLEAN simpleOutput);
526
* Fill referenceList with object references. Given object can be also an
529
static void gci_getReferences(void* object,
530
XanList* referenceList,
531
XanList* fieldsLayout,
533
JITBOOLEAN isValueType);
535
/* Run some cleanup tasks when a given thread die */
536
static void gci_threadExit(pthread_t threadID);
539
* Fill referenceList with object references. Given object can be also an
542
static void gci_getReferences(void* object,
543
XanList* referenceList,
544
XanList* fieldsLayout,
546
JITBOOLEAN isValueType)
548
/* Current array element, if given object is an array */
551
/* Given object header, if the object is an array */
552
t_arrayHeader* arrayHeader;
554
/* Object layout infos */
555
ILLayout* layoutInfos;
557
/* A IR machine type */
562
/* Given object field container */
563
XanListItem* currentField;
565
/* Given object field layout */
566
ILFieldLayout* currentFieldLayout;
568
/* Address of a field of given object */
572
assert(object != NULL);
573
assert(referenceList != NULL);
574
assert(fieldsLayout != NULL);
576
PDEBUG("GC: getReferences: Start\n");
578
/* Fetch the system */
579
system = getSystem(NULL);
580
assert(system != NULL);
582
/* Given object is an array */
585
/* Retrieve the array header */
586
arrayHeader = GET_ARRAY_HEADER(object);
588
/* Retrieve array layout info */
589
layoutInfos = (ILLayout*) arrayHeader->layoutInfos;
591
/* Add all array elements to references objects */
592
for(count = 0; count < arrayHeader->dimSize; count++)
594
/* Array stores basic values */
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)
602
fieldAddress = object +
604
layoutInfos->typeSize;
609
layoutInfos->fieldsLayout,
613
/* Array dont't stores basic values */
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 +
627
layoutInfos->fieldsLayout,
634
/* We are examing a real object */
636
/* Visit each object field */
637
currentField = fieldsLayout->first(fieldsLayout);
638
while(currentField != NULL)
640
/* Retrieve the current field layout informations */
641
currentFieldLayout = fieldsLayout->data(fieldsLayout,
644
/* Current field stores a basic value */
645
if(currentFieldLayout->IRType == IRVALUETYPE)
647
/* Retrieve the fields layout for the valuetype */
649
(ILLayout*) currentFieldLayout->layout;
651
/* Get field address */
652
fieldAddress = object +
653
currentFieldLayout->offset;
655
/* Find references on current field */
656
gci_getReferences(fieldAddress, referenceList,
657
layoutInfos->fieldsLayout,
660
/* Current field stores a reference */
661
else if(currentFieldLayout->IRType == IROBJECT)
663
fieldAddress = object + currentFieldLayout->offset;
665
PDEBUG("GC: getReferences: Found a reference"
666
" = %p\n", fieldAddress);
668
/* The found reference points to something */
669
if(fieldAddress != NULL)
670
referenceList->insert(referenceList,
674
/* Retrieve the next field */
675
currentField = fieldsLayout->next(fieldsLayout,
680
PDEBUG("GC: getReferences: Exit\n");
686
/* Get objects referenced by given object */
687
XanList* getReferencedObject(void* object)
689
/* Given object header */
690
t_objectHeader* objectHeader;
692
/* Enabled if given object is an array */
695
/* Enabled if given object is an array that stores basic type */
696
JITBOOLEAN isValueType;
698
/* A list of references */
699
XanList* referenceList;
701
/* Object layout infos */
704
/* Object layout infos, if static */
705
ILLayoutStatic* layoutStatic;
707
/* Given object fields layout */
708
XanList* fieldsLayout;
711
assert(object != NULL);
712
PDEBUG("GC: getReferencedObject: Start\n");
714
/* Initialize local variables */
715
isValueType = JITFALSE;
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");
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);
728
/* Given object is an array */
729
if(HAS_ARRAY_FLAG(objectHeader)) {
730
PDEBUG("GC: getReferencedObject: The instance is an array\n");
732
/* Set the isArray flag */
735
/* Array stores basic types */
736
if(HAS_VALUETYPE_FLAG(objectHeader)) {
737
PDEBUG("GC: getReferencedObject: The instance is a value type\n");
739
/* Set the isValueType flag */
740
isValueType = JITTRUE;
743
/* Given object is a normal object */
746
PDEBUG("GC: getReferencedObject: "
747
"The instance is a normal object\n");
752
/* Given object is static */
753
if(HAS_STATIC_FLAG(objectHeader))
755
PDEBUG("GC: getReferencedObject: "
756
"The instance is static\n");
758
/* Retrieve the fields layout informations */
759
layoutStatic = (ILLayoutStatic*) objectHeader->layoutInfos;
760
fieldsLayout = layoutStatic->fieldsLayout;
762
/* Given object is a normal object */
765
PDEBUG("GC: getReferencedObject: "
766
"The instance is not static\n");
768
/* Retrieve the fields layout informations */
769
layout = (ILLayout*) objectHeader->layoutInfos;
770
fieldsLayout = layout->fieldsLayout;
773
PDEBUG("GC: getReferencedObject: Check if exist some fields of this object\n");
775
/* Given object has some field? */
776
if(fieldsLayout == NULL)
778
PDEBUG("GC: getReferencedObject: No fields\n");
783
PDEBUG("GC: getReferencedObject: "
785
PDEBUG("GC: getReferencedObject: "
786
"Retrieve the references\n");
788
/* Retrive the references */
789
gci_getReferences(object, referenceList, fieldsLayout,
790
isArray, isValueType);
793
PDEBUG("GC: getReferencedObject: Exit\n");
796
return referenceList;
799
/* Check if given object is collectable */
800
JITBOOLEAN isCollectable(void* object)
803
JITBOOLEAN collectable;
806
assert(object != NULL);
808
PDEBUG("GC: isCollectable: START \n");
810
/* Object uncollectable */
811
if(gci_isStatic(object) || gci_isPermanent(object))
813
collectable = JITFALSE;
814
PDEBUG("GC: isCollectable: END - NOT COLLECTABLE\n");
816
/* Object collectable */
819
collectable = JITTRUE;
820
PDEBUG("GC: isCollectable: END - COLLECTABLE \n");
826
/* Returns current root set */
827
XanList* getRootSet(void)
829
/* Root set slot index */
832
/* System properties and functions */
835
/* Currently running garbage collector */
836
t_garbage_collector_plugin* garbageCollector;
838
/* System reflection manager */
839
t_reflectManager* reflectionManager;
841
/* List of root sets */
842
XanList* threadsRootSets;
844
/* A root set container */
845
XanListItem* threadRootSetItem;
847
/* Root set of a thread */
848
t_root_sets* threadRootSet;
850
/* Error message buffer */
851
char buffer[DIM_BUF];
853
/* Object reference in the root set */
854
void** objectReference;
861
assert(rootSetList == NULL);
863
PDEBUG("GC: getRootSet: Start\n");
865
/* Lock the root sets */
866
rootSets->lock(rootSets);
868
/* Allocate the new list */
869
rootSetList = xanListNew(allocFunction, freeFunction, NULL);
871
/* Get all we need */
872
system = getSystem(NULL);
873
garbageCollector = system->garbage_collectors.gc.gc_plugin;
874
reflectionManager = &(system->reflectManager);
876
/* Check if the current GC needs this kind of support */
877
if(!GC_NEEDS_ROOTSET(garbageCollector))
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);
888
PDEBUG("GC: getRootSet: Add the slots from the methods stack "
889
"to the root set\n");
891
/* Cycle throught all threads root sets */
892
threadsRootSets = rootSets->toList(rootSets);
893
threadRootSetItem = threadsRootSets->first(threadsRootSets);
894
while(threadRootSetItem != NULL)
896
/* Retrive root set */
897
threadRootSet = threadRootSetItem->data;
899
/* Add the normal objects */
901
objectReference = threadRootSet->getRootSetSlot(threadRootSet, &count);
903
while(objectReference != NULL) {
905
/* Current reference points to something */
906
if((*objectReference) != NULL){
907
assert(rootSetList != NULL);
908
rootSetList->insert(rootSetList, objectReference);
912
objectReference = threadRootSet->getRootSetSlot(threadRootSet, &count);
916
/* Fetch the next thread root set container */
917
threadRootSetItem = threadsRootSets->next(threadsRootSets, threadRootSetItem);
920
/* Add the static objects */
921
rootSetList->synchAppendList(rootSetList, system->staticMemoryManager->staticObjects->toSlotList(system->staticMemoryManager->staticObjects));
923
/* Add the objects of the reflection library */
924
if(reflectionManager->clrTypes != NULL){
925
rootSetList->appendList(rootSetList, reflectionManager->clrTypes->toSlotList( reflectionManager->clrTypes));
927
if(reflectionManager->clrAssemblies != NULL){
928
rootSetList->appendList(rootSetList, reflectionManager->clrAssemblies->toSlotList( reflectionManager->clrAssemblies));
930
if(reflectionManager->clrProperties != NULL){
931
rootSetList->appendList(rootSetList, reflectionManager->clrProperties->toSlotList( reflectionManager->clrProperties));
933
if(reflectionManager->clrMethods != NULL){
934
rootSetList->appendList(rootSetList, reflectionManager->clrMethods->toSlotList( reflectionManager->clrMethods));
936
if(reflectionManager->clrConstructors != NULL){
937
rootSetList->appendList(rootSetList, reflectionManager->clrConstructors->toSlotList(reflectionManager->clrConstructors));
939
if(reflectionManager->clrFields != NULL){
940
rootSetList->appendList(rootSetList, reflectionManager->clrFields->toSlotList(reflectionManager->clrFields));
942
if(reflectionManager->clrEvents != NULL){
943
rootSetList->appendList(rootSetList, reflectionManager->clrEvents->toSlotList(reflectionManager->clrEvents));
945
if(reflectionManager->clrParameter != NULL){
946
rootSetList->appendList(rootSetList, reflectionManager->clrParameter->toSlotList(reflectionManager->clrParameter));
948
if(reflectionManager->clrModule != NULL){
949
rootSetList->appendList(rootSetList, reflectionManager->clrModule->toSlotList(reflectionManager->clrModule));
954
rootSetList->appendList(rootSetList, ((system->stringManager).usObjects)->toSlotList((system->stringManager).usObjects));
955
rootSetList->appendList(rootSetList, ((system->stringManager).internHashTable)->toSlotList((system->stringManager).internHashTable));
957
/* Add the OutOfMemory exception */
958
rootSetList->insert(rootSetList, &(system->exception_system._OutOfMemoryException));
961
/* Print the root set */
962
PDEBUG("GC: getRootSet: Root set\n");
963
item = rootSetList->first(rootSetList);
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);
972
#endif /* PRINTDEBUG */
974
/* Unlock the root sets */
975
rootSets->unlock(rootSets);
977
/* Return the root set */
981
/* Get given object size */
982
JITNUINT sizeObject(void* object)
984
/* Given object header */
985
t_objectHeader* objectHeader;
987
/* Given object total size */
988
JITUINT32 overallSize;
991
assert(object != NULL);
993
PDEBUG("GC: sizeObject: Start\n");
995
/* Retrieve the pointer to the header of the object */
996
objectHeader = GET_OBJECT_HEADER(object);
998
/* Retrieve the overall size of the instance */
999
overallSize = objectHeader->objectSize;
1001
/* Print the overall size */
1002
PDEBUG("GC: sizeObject: Size = %u\n", overallSize);
1004
/* Return the value */
1008
/* Print given object runtime values, e.g. fields values */
1009
static void gci_printRuntimeValues(void* object,
1010
XanList* fieldsLayout,
1012
JITBOOLEAN simpleOutput)
1014
/* Given array header, if given object is an array */
1015
t_arrayHeader* arrayHeader;
1017
/* Array cell index, if given object is an array */
1020
/* Array cell layout, if given object is an array */
1021
ILLayout* layoutInfos;
1023
/* Address of a field of given object */
1026
/* Given object current field container */
1027
XanListItem* currentField;
1029
/* Given object current field layout */
1030
ILFieldLayout* currentFieldLayout;
1033
assert(object != NULL);
1034
assert(fieldsLayout != NULL);
1036
/* We are printing an array */
1038
/* Retrieve the array header */
1039
arrayHeader = GET_ARRAY_HEADER(object);
1042
PDEBUG("GC: printObject: ARRAY RUNTIME VALUES "
1043
"------ start ------ \n");
1045
/* Array stores basic types */
1046
if(HAS_VALUETYPE_FLAG(arrayHeader))
1048
/* Get layout infos */
1049
layoutInfos = (ILLayout*) arrayHeader->layoutInfos;
1052
* Print array elements values (they are basic, such as
1055
for(count = 0; count < arrayHeader->dimSize; count++)
1058
PDEBUG("array[%d] - VALUE : \n", count);
1060
fieldAddress = object + layoutInfos->typeSize * count;
1061
gci_printRuntimeValues(fieldAddress,
1067
/* Array stores references */
1070
/* Print array element values */
1071
for(count = 0; count < arrayHeader->dimSize; count++)
1073
fieldAddress = object + count * sizeof(JITNUINT);
1074
PDEBUG("array[%d] - VALUE : %p\n", count,
1075
(void*) *((JITNUINT*) fieldAddress));
1079
/* We are printing a normal object */
1083
PDEBUG("GC: printObject: RUNTIME VALUES "
1084
"------ start ------ \n");
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,
1093
/* Print the infos about the value of the current field */
1094
gci_printFieldInfo(object, currentFieldLayout, NULL,
1097
/* Retrieve the next field */
1098
currentField = fieldsLayout->next(fieldsLayout, currentField);
1104
PDEBUG("GC: printObject: RUNTIME VALUES ------ end ------ \n");
1107
/* Unset permanent flag from given object */
1108
static void gci_unsetPermanentFlag(void* object)
1110
t_objectHeader *objectHeader;
1113
assert(object != NULL);
1115
/* Retrieve the pointer to the header of the object */
1116
objectHeader = GET_OBJECT_HEADER(object);
1118
/* Unset the permanent flag */
1119
objectHeader->flags &= (IS_ARRAY | IS_VALUETYPE | IS_STATIC);
1122
static void gci_setFinalizedFlag(void* object){
1123
/* Given object header */
1124
t_objectHeader *objectHeader;
1127
assert(object != NULL);
1129
/* Retrieve the pointer to the header of the object */
1130
objectHeader = GET_OBJECT_HEADER(object);
1132
/* Set the static flag */
1133
objectHeader->flags |= IS_FINALIZED;
1136
/* Set permanent flag on given object */
1137
static void gci_setPermanentFlag(void* object)
1139
/* Given object header */
1140
t_objectHeader *objectHeader;
1143
assert(object != NULL);
1145
/* Retrieve the pointer to the header of the object */
1146
objectHeader = GET_OBJECT_HEADER(object);
1148
/* Set the static flag */
1149
objectHeader->flags |= IS_COLLECTABLE;
1152
/* Set IS_STATIC flag on given object */
1153
static void gci_setStaticFlag(void* object)
1155
/* Given object header */
1156
t_objectHeader* objectHeader;
1159
assert(object != NULL);
1161
/* Retrieve the pointer to the header of the object */
1162
objectHeader = GET_OBJECT_HEADER(object);
1164
/* Set the static flag */
1165
objectHeader->flags |= IS_STATIC;
1168
static JITBOOLEAN gci_isFinalized(void* object){
1169
/* Given object header */
1170
t_objectHeader* header;
1173
assert(object != NULL);
1175
/* Get object header */
1176
header = GET_OBJECT_HEADER(object);
1178
/* Retrieve the information */
1179
return HAS_FINALIZED_FLAG(header);
1182
/* Check if an object is permanent */
1183
static JITBOOLEAN gci_isPermanent(void* object)
1185
/* Given object header */
1186
t_objectHeader* header;
1189
assert(object != NULL);
1191
/* Get object header */
1192
header = GET_OBJECT_HEADER(object);
1194
/* Retrieve the information */
1195
return HAS_COLLECTABLE_FLAG(header);
1198
/* Check if given object is static */
1199
static JITBOOLEAN gci_isStatic(void* object)
1201
/* Given object header */
1202
t_objectHeader* header;
1205
assert(object != NULL);
1207
/* Get object header */
1208
header = GET_OBJECT_HEADER(object);
1210
/* Check for IS_STATIC flag */
1211
return HAS_STATIC_FLAG(header);
1215
/* Check if given object is an array */
1216
static JITBOOLEAN gci_isArray(void* object)
1218
/* Given object header */
1219
t_objectHeader* header;
1222
assert(object != NULL);
1224
/* Get object header */
1225
header = GET_OBJECT_HEADER(object);
1227
/* Check for IS_STATIC flag */
1228
return HAS_ARRAY_FLAG(header);
1232
/* Get a pointer to given object virtual table */
1233
static void** gci_getVTable(void* object)
1235
/* Given object header */
1236
t_objectHeader* objectHeader;
1239
assert(object != NULL);
1241
/* Get object header */
1242
objectHeader = GET_OBJECT_HEADER(object);
1244
/* Return the pointer that address the virtual table of the object */
1245
return objectHeader->virtualTable;
1248
/* Get given object binary code */
1249
static void* gci_getBinary(void* object)
1251
/* Given object header */
1252
t_objectHeader* objectHeader;
1254
/* Object layout infos */
1255
ILLayout* layoutInfos;
1258
assert(object != NULL);
1260
/* Retrieve the pointer to the header of the object */
1261
objectHeader = GET_OBJECT_HEADER(object);
1263
/* Retrieve the pointer to the layout informations */
1264
layoutInfos = objectHeader->layoutInfos;
1266
/* Return object binary code */
1267
return layoutInfos->type->binary;
1270
/* Get the IR type of array elements */
1271
static JITUINT32 gci_getArraySlotIRType(void* array)
1273
/* Given array header */
1274
t_arrayHeader* header;
1276
/* Given array layout infos */
1282
assert(array != NULL);
1284
/* Fetch the system */
1285
system = getSystem(NULL);
1286
assert(system != NULL);
1288
/* Retrieve the array header */
1289
header = GET_ARRAY_HEADER(array);
1291
/* Retrieve the layout infos */
1292
infos = (ILLayout*) header->layoutInfos;
1294
/* Return the array slot type */
1295
return get_IR_type_from_ILType(system->type_checker, infos->type, system->binaries);
1298
static JITINT32 gci_getObjectLayoutOffset(void) {
1299
t_objectHeader objectHeader;
1300
JITNUINT objectHeaderAddress;
1301
JITNUINT objectLayoutAddress;
1304
/* Compute the offset */
1305
objectHeaderAddress = (JITNUINT) &objectHeader;
1306
objectLayoutAddress = (JITNUINT) &(objectHeader.layoutInfos);
1307
offset = objectLayoutAddress - objectHeaderAddress - HEADER_FIXED_SIZE;
1309
/* Return computed offset */
1313
/* Get array header dimSize offset from a generic IR machine array address */
1314
static JITINT32 gci_getArrayLengthOffset(void)
1316
/* A generic array header */
1317
t_arrayHeader arrayHeader;
1319
/* Pointer to a generic array header */
1320
JITNUINT arrayHeaderAddress;
1322
/* Address of dimSize field in a generic array header */
1323
JITNUINT arrayLengthAddress;
1325
/* dimSize field offset */
1328
PDEBUG("GC: getArrayLengthOffset: Start\n");
1330
/* Compute the offset */
1331
arrayHeaderAddress = (JITNUINT) &arrayHeader;
1332
arrayLengthAddress = (JITNUINT) &(arrayHeader.dimSize);
1333
offset = arrayLengthAddress - arrayHeaderAddress - HEADER_FIXED_SIZE;
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",
1341
PDEBUG("GC: getArrayLengthOffset: Exit\n");
1343
/* Return computed offset */
1347
/* Get given array rank */
1348
static JITUINT16 gci_getArrayRank(void* array)
1350
/* Given array header */
1351
t_arrayHeader* header;
1354
assert(array != NULL);
1356
/* Retrieve the array header */
1357
header = GET_ARRAY_HEADER(array);
1359
/* Return the array rank */
1360
return header->rank;
1363
/* Get given array length */
1364
static JITUINT32 gci_getArrayLength(void* array)
1366
/* Given array header */
1367
t_arrayHeader* header;
1370
assert(array != NULL);
1372
PDEBUG("GC: getArrayLength: Start\n");
1374
/* Retrieve the array header */
1375
header = GET_ARRAY_HEADER(array);
1377
PDEBUG("GC: getArrayLength: Array length = %d\n", header->dimSize);
1378
PDEBUG("GC: getArrayLength: Exit\n");
1380
/* Return the length of the array */
1381
return header->dimSize;
1384
/* Get methodID index in virtual table of binaryInfo */
1385
static JITUINT32 gci_getIndexOfVTable(t_binary_information* binaryInfo,
1386
ILMethodID methodID)
1388
/* Virtual table entry */
1389
t_virtual_method* internalVMethod;
1391
/* System layout manager */
1392
ILLayout_manager* layoutManager;
1394
/* Type of virtual table owner */
1397
/* Virtual table owner metadata streams */
1398
t_streams_metadata* streams;
1400
/* Type definiton table */
1401
t_type_def_table* typeDefTable;
1404
/* Method name, used in debug */
1406
#endif /* PRINTDEBUG */
1409
assert(binaryInfo != NULL);
1411
PDEBUG("GC: getIndexOfVTable: Start\n");
1413
/* Get layout manager */
1414
layoutManager = getSystem(NULL)->layout_manager;
1416
/* Fetch the binary */
1417
ownerType.binary = binaryInfo;
1419
/* Fetch the streams */
1420
streams = &(ownerType.binary->metadata.streams_metadata);
1421
typeDefTable = get_table(&(streams->not_stream.tables), TYPE_DEF_TABLE);
1423
/* Fetch the class where the method is stored */
1424
ownerType.ID = typeDefTable->get_type_from_method(streams, methodID);
1426
/* Print the method name */
1428
name = get_string(&(streams->string_stream), methodID->name);
1429
PDEBUG("GC: getIndexOfVTable: Method = %s\n", name);
1430
#endif /* PRINTDEBUG */
1432
/* Fetch the method */
1433
internalVMethod = layoutManager->lookupMethod(layoutManager,
1437
PDEBUG("GC: getIndexOfVTable: Index = %u\n",
1438
internalVMethod->index);
1439
PDEBUG("GC: getIndexOfVTable: Exit\n");
1441
/* Return method index in the virtual table */
1442
return internalVMethod->index;
1445
/* Get given field type */
1446
static JITUINT32 gci_getFieldType(t_binary_information* binaryInfo,
1449
/* System layout manager */
1450
ILLayout_manager* layoutManager;
1452
/* Field owner type */
1455
/* Field owner metadata streams */
1456
t_streams_metadata* streamsMetadata;
1458
/* Describe the field with given fieldID */
1461
/* Info about given field owner layout */
1462
ILLayout* layoutInfos;
1464
/* Info about given static field owner layout */
1465
ILLayoutStatic* staticLayoutInfos;
1467
/* Info about field layout */
1468
ILFieldLayout* fieldInfos;
1471
assert(binaryInfo != NULL);
1473
/* Get system layout manager */
1474
layoutManager = getSystem(NULL)->layout_manager;
1476
/* Setup query parameters */
1477
memset(&ownerType, 0, sizeof(ILType));
1478
ownerType.binary = binaryInfo;
1479
memset(&field, 0, sizeof(ILField));
1481
field.binary = binaryInfo;
1483
/* Fetch the type that defines this field */
1484
streamsMetadata = &(ownerType.binary->metadata.streams_metadata);
1485
ownerType.ID = fieldID->get_owner_Type(streamsMetadata, fieldID);
1487
/* The given field is STATIC */
1488
if (fieldID->flags & 0x10) {
1489
/* Retrive the field layout informations */
1490
staticLayoutInfos = layoutManager->layoutStaticType(
1493
fieldInfos = staticLayoutInfos->fetchStaticFieldLayout(
1496
/* The given field isn't STATIC */
1500
layoutInfos = layoutManager->layoutType(layoutManager,
1502
fieldInfos = layoutInfos->fetchFieldLayout(layoutInfos,
1506
/* Return the IR-Type */
1507
return fieldInfos->IRType;
1510
/* Get virtual table offset */
1511
JITINT32 gci_fetchVTableOffset(void)
1513
return -HEADER_FIXED_SIZE;
1516
/* Get given static field offset from its owner start address */
1517
static JITINT32 gci_fetchStaticFieldOffset(
1518
t_binary_information* binaryInfo,
1522
/* System layout manager */
1523
ILLayout_manager* layoutManager;
1525
/* Field owner type */
1528
/* Describe given field */
1531
/* Field metadata streams */
1532
t_streams_metadata* streamsMetadata;
1534
/* Field owner layout info */
1535
ILLayoutStatic* layoutInfos;
1537
/* Field layout info */
1538
ILFieldLayout* fieldInfos;
1541
assert(binaryInfo != NULL);
1543
/* Get system layout manager*/
1544
layoutManager = getSystem(NULL)->layout_manager;
1546
/* Initialize variables for the query */
1547
memset(&ownerType, 0, sizeof(ILType));
1548
ownerType.binary = binaryInfo;
1550
field.binary = binaryInfo;
1552
/* Retrieve the owner of the field */
1553
streamsMetadata = &(field.binary->metadata.streams_metadata);
1554
ownerType.ID = (ILClassID) fieldID->get_owner_Type(streamsMetadata,
1557
/* Retrieve the layout informations of ownerType */
1558
layoutInfos = layoutManager->layoutStaticType(layoutManager,
1561
/* Retrieve the field layout informations */
1562
fieldInfos = layoutInfos->fetchStaticFieldLayout(layoutInfos, &field);
1564
/* Return the offset of the field */
1565
return fieldInfos->offset;
1568
/* Get given field offset from its owner start address */
1569
static JITINT32 gci_fetchFieldOffset(t_binary_information* binaryInfo,
1573
ILLayout_manager* layoutManager;
1575
/* The ILType of the object that owns the current field */
1578
/* The field with given fieldID */
1581
/* Field metadata streams */
1582
t_streams_metadata* streamsMetadata;
1584
/* Information about field owner layout */
1585
ILLayout* layoutInfos;
1587
/* Information about field layout */
1588
ILFieldLayout* fieldInfos;
1591
assert(binaryInfo != NULL);
1593
/* Get system layout manager */
1594
layoutManager = getSystem(NULL)->layout_manager;
1596
/* Initialize variables for the query */
1597
memset(&ownerType, 0, sizeof(ILType));
1598
ownerType.binary = binaryInfo;
1600
field.binary = binaryInfo;
1602
/* Retrieve the owner of the field */
1603
streamsMetadata = &(field.binary->metadata.streams_metadata);
1604
ownerType.ID = (ILClassID) fieldID->get_owner_Type(streamsMetadata,
1607
/* Retrieve the layout informations of ownerType */
1608
layoutInfos = layoutManager->layoutType(layoutManager, &ownerType);
1611
debug_print_layout_informations(layoutInfos);
1614
/* Retrieve the field layout informations */
1615
fieldInfos = layoutInfos->fetchFieldLayout(layoutInfos, &field);
1617
/* Return the offset of the field */
1618
return fieldInfos->offset;
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)
1628
/* Given field layout, if it is a VALUETYPE */
1629
ILLayout* valueTypeLayout;
1631
/* VALUETYPE field layout */
1632
ILFieldLayout* VTFieldLayout;
1634
/* VALUETYPE fields list */
1635
XanList* fieldsLayout;
1637
/* Current VALUETYPE field container */
1638
XanListItem* currentVTField;
1641
assert(object != NULL);
1642
assert(currentFieldLayout != NULL);
1644
/* Retrieve the field name */
1645
if(optionalString == NULL)
1646
optionalString = get_name_from_fieldInfo(
1647
currentFieldLayout->field);
1649
/* Print field info */
1650
switch(currentFieldLayout->IRType)
1656
PDEBUG("%d", GET_FIELD_VALUE(JITINT16, object,
1661
PDEBUG("%s - VALUE : %d\n", optionalString,
1662
GET_FIELD_VALUE(JITINT16, object,
1668
/* Integer 32 bit */
1671
PDEBUG("%d", GET_FIELD_VALUE(JITINT32, object,
1676
PDEBUG("%s - VALUE : %d\n", optionalString,
1677
GET_FIELD_VALUE(JITINT32, object,
1683
/* Integer 16 bit, also used for chars */
1687
if(currentFieldLayout->isChar)
1688
PDEBUG("%c", GET_FIELD_VALUE(JITINT16, object,
1693
PDEBUG("%d", GET_FIELD_VALUE(JITINT16, object,
1700
if(currentFieldLayout->isChar)
1701
PDEBUG("%s - VALUE : %c\n", optionalString,
1702
GET_FIELD_VALUE(JITINT16, object,
1707
PDEBUG("%s - VALUE : %d\n", optionalString,
1708
GET_FIELD_VALUE(JITINT16, object,
1715
/* Integer 64 bit */
1718
PDEBUG("%lld", GET_FIELD_VALUE(JITINT64, object,
1723
PDEBUG("%s - VALUE : %lld\n", optionalString,
1724
GET_FIELD_VALUE(JITINT64, object,
1730
/* Integer native */
1733
PDEBUG("%d", GET_FIELD_VALUE(JITNINT, object,
1738
PDEBUG("%s - VALUE : %d\n", optionalString,
1739
GET_FIELD_VALUE(JITNINT, object,
1745
/* Integer Unsigned 8 bit and Integer Unsigned 16 bit */
1749
PDEBUG("%d", GET_FIELD_VALUE(JITUINT16, object,
1754
PDEBUG("%s - VALUE : %d\n", optionalString,
1755
GET_FIELD_VALUE(JITUINT16, object,
1761
/* Integer Unsigned 32 bit */
1764
PDEBUG("%d", GET_FIELD_VALUE(JITUINT32, object,
1769
PDEBUG("%s - VALUE : %d\n", optionalString,
1770
GET_FIELD_VALUE(JITUINT32, object,
1776
/* Integer Unsigned 64 bit */
1779
PDEBUG("%lld", GET_FIELD_VALUE(JITUINT64, object,
1784
PDEBUG("%s - VALUE : %lld\n", optionalString,
1785
GET_FIELD_VALUE(JITUINT64, object,
1791
/* Integer Native Unsigned */
1794
PDEBUG("%d", GET_FIELD_VALUE(JITNUINT, object,
1799
PDEBUG("%s - VALUE : %d\n", optionalString,
1800
GET_FIELD_VALUE(JITNUINT, object,
1809
PDEBUG("%f", GET_FIELD_VALUE(JITFLOAT32, object,
1814
PDEBUG("%s - VALUE : %f\n", optionalString,
1815
GET_FIELD_VALUE(JITFLOAT32, object,
1824
PDEBUG("%f", GET_FIELD_VALUE(JITFLOAT64, object,
1829
PDEBUG("%s - VALUE : %f\n", optionalString,
1830
GET_FIELD_VALUE(JITFLOAT64, object,
1839
PDEBUG("%f", GET_FIELD_VALUE(JITNFLOAT, object,
1844
PDEBUG("%s - VALUE : %f\n", optionalString,
1845
GET_FIELD_VALUE(JITNFLOAT, object,
1851
/* Pointers and addresses */
1857
PDEBUG("%p", (void*) GET_FIELD_VALUE(JITNUINT, object,
1862
PDEBUG("%s - VALUE : %p\n", optionalString,
1863
(void*) GET_FIELD_VALUE(JITNUINT, object,
1869
/* VALUETYPE or TYPED REFerences */
1872
/* Initialize the value of layout */
1873
valueTypeLayout = (ILLayout*) currentFieldLayout->layout;
1875
PDEBUG("%s - VALUETYPE [%s]--- RUNTIME VALUES --- START \n",
1877
get_name_from_typeInfo(valueTypeLayout->type)
1880
/* Get fields layout list */
1881
fieldsLayout = valueTypeLayout->fieldsLayout;
1883
/* Print the values of object */
1884
currentVTField = fieldsLayout->first(fieldsLayout);
1885
while(currentVTField != NULL)
1887
/* Retrieve the current field layout informations */
1888
VTFieldLayout = fieldsLayout->data(fieldsLayout,
1891
/* Print the infos about current field value */
1892
gci_printFieldInfo(object, VTFieldLayout, NULL,
1894
currentFieldLayout->offset,
1897
/* Retrieve the next field */
1898
currentVTField = fieldsLayout->next(fieldsLayout,
1901
PDEBUG("%s - VALUETYPE --- RUNTIME VALUES --- END\n",
1905
/* Error: unknown field type */
1907
PDEBUG("gc_INTERACTIONS : printFieldInfo: ERROR! \n");
1908
print_err("gc_INTERACTIONS : printFieldInfo: ERROR!", 0);
1913
static void gci_collect (void){
1916
/* Fetch the system */
1917
system = getSystem(NULL);
1918
assert(system != NULL);
1920
/* Run the collection */
1921
(system->garbage_collectors).gc.gc_plugin->collect();
1923
/* Check if the garbage *
1924
* collector has called the *
1925
* getRootSet method. */
1926
if(rootSetList != NULL) {
1927
rootSetList->destroyList(rootSetList);
1930
assert(rootSetList == NULL);
1936
/* Print given object via debug macro */
1937
static void gci_printObject (void* object, char* prefix) {
1938
/* Given object header */
1939
t_objectHeader* objectHeader;
1941
/* Given array header, if object is an array */
1942
t_arrayHeader* arrayHeader;
1945
ILLayoutStatic* staticLayout;
1948
/* Layout of each object field */
1949
XanList* fieldsLayout;
1951
/* Enabled if we are printing an array */
1955
assert(prefix != NULL);
1957
PDEBUG("GC: printObject: %s: Start\n", prefix);
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);
1966
/* Initialize the fieldsLayout list */
1967
fieldsLayout = NULL;
1969
/* Initialize the `isArray` local variable */
1972
/* retrieve the pointer to the header of the object */
1973
objectHeader = GET_OBJECT_HEADER(object);
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,
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);
1985
/* Print object collectable info */
1986
if(HAS_COLLECTABLE_FLAG(objectHeader)){
1987
PDEBUG("GC: printObject: %s: object is collectable \n", prefix);
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);
1995
/* Print additional info if the object is an array */
1996
if(HAS_ARRAY_FLAG(objectHeader))
1998
/* Retrive the pointer to the t_arrayHeader structure */
1999
arrayHeader = (t_arrayHeader *) objectHeader;
2001
/* Set the `isArray` flag */
2004
PDEBUG("GC: printObject: %s: object is an Array \n",
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",
2012
/* Print array general info */
2013
PDEBUG("GC: printObject: %s: object is an Array \n",
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);
2021
/* Print out all the layout informations associated with the object */
2022
if(HAS_STATIC_FLAG(objectHeader))
2024
/* Get layout object */
2025
staticLayout = (ILLayoutStatic*) objectHeader->layoutInfos;
2027
/* Print debug info */
2028
debug_print_layoutStatic_informations(staticLayout);
2030
/* Retrieve the fieldsLayout informations */
2031
fieldsLayout = staticLayout->fieldsLayout;
2033
/* Object haven't IS_STATIC flag */
2036
/* Notifiy that we are printing an array */
2038
PDEBUG("GC: printObject: %s: ---- %s %s: ----\n",
2039
"EACH ELEMENT OF THE ARRAY",
2040
"HAS THESE LAYOUT INFOS", prefix);
2043
/* Retrive an print layout info */
2044
layout = (ILLayout*) objectHeader->layoutInfos;
2045
debug_print_layout_informations(layout);
2047
/* Retrieve the fieldsLayout informations */
2048
fieldsLayout = layout->fieldsLayout;
2051
/* No field on current object? */
2052
if (fieldsLayout == NULL) {
2053
PDEBUG("GC: printObject: %s: Exit\n", prefix);
2057
/* Print the runtime values */
2058
gci_printRuntimeValues(object, fieldsLayout, isArray, JITFALSE);
2060
PDEBUG("GC: printObject: %s: Exit\n", prefix);
2063
/* Alloc a new array */
2064
static void* gci_allocArray(t_binary_information* binaryInfo,
2069
/* Array elements type */
2076
assert(binaryInfo != NULL);
2078
PDEBUG("GC: allocArray: Start\n");
2079
PDEBUG("GC: allocArray: Rank = %d \n", rank);
2080
PDEBUG("GC: allocArray: Size = %d \n", size);
2082
/* Build object type */
2083
memset(&objectType, 0, sizeof(ILType));
2084
objectType.ID = classID;
2085
objectType.binary = binaryInfo;
2087
/* Create a new array */
2088
newArray = gci_createArray(&objectType, JITTRUE, rank, size);
2089
PDEBUG("GC: allocArray: New array = %p\n", newArray);
2091
/* Return the just created array instance */
2092
PDEBUG("GC: allocArray: Exit\n");
2096
/* Alloc a new static object */
2097
static void* gci_allocStaticObject(t_binary_information* binaryInfo,
2101
/* Object IL type description */
2105
assert(binaryInfo != NULL);
2107
/* Build object type description */
2108
memset(&objectType, 0, sizeof(ILType));
2109
objectType.ID = classID;
2110
objectType.binary = binaryInfo;
2112
/* Create a permanent new instance */
2113
return gci_createInstance(&objectType, overSize, JITFALSE, JITTRUE);
2116
/* Alloc a new normal object */
2117
static void* gci_allocObject(t_binary_information* binaryInfo,
2121
/* New object type */
2128
assert(binaryInfo != NULL);
2130
PDEBUG("GC: allocObject: Start\n");
2131
PDEBUG("GC: allocObject: Binary = %s\n", binaryInfo->name);
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;
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);
2144
/* Return the just created instance */
2145
PDEBUG("GC: allocObject: Exit\n");
2149
/* Create a new permanent object */
2150
static void* gci_allocPermanentObject(
2151
t_binary_information* binaryInfo,
2156
/* Object description */
2160
assert(binaryInfo != NULL);
2162
/* Build object description */
2163
memset(&objectType, 0, sizeof(ILType));
2164
objectType.ID = classID;
2165
objectType.binary = binaryInfo;
2167
/* Try to alloc a new object */
2168
return gci_createInstance(&objectType, overSize, JITFALSE, JITFALSE);
2171
/* Unset given object STATIC flag */
2172
static void gci_unsetStaticFlag(void* object)
2174
/* Given object header */
2175
t_objectHeader* objectHeader;
2178
assert(object != NULL);
2180
/* Retrieve the pointer to the header of the object */
2181
objectHeader = GET_OBJECT_HEADER(object);
2183
/* Unset the static flag */
2184
objectHeader->flags &= (IS_ARRAY | IS_VALUETYPE | IS_COLLECTABLE);
2187
/* Get the oversize offset of the given object */
2188
static JITINT32 gci_fetchOverSizeOffset(void* object)
2191
t_objectHeader* objectHeader;
2194
t_arrayHeader* arrayHeader;
2196
/* Object/Array layout */
2197
ILLayout* layoutInfos;
2199
/* Object layout (static version) */
2200
ILLayoutStatic* staticLayoutInfos;
2202
/* The oversize offset */
2203
JITUINT32 oversizeOffset;
2205
/* Array element size */
2208
/* Array element IR type */
2214
assert(object != NULL);
2216
/* Fetch the system */
2217
system = getSystem(NULL);
2218
assert(system != NULL);
2220
/* Fetch object header */
2221
objectHeader = GET_OBJECT_HEADER(object);
2223
/* Given object is an array */
2224
if(HAS_ARRAY_FLAG(objectHeader))
2226
/* Retrieve the array header */
2227
arrayHeader = (t_arrayHeader*) objectHeader;
2229
/* Retrieve the layout infos */
2230
layoutInfos = (ILLayout*) arrayHeader->layoutInfos;
2232
/* Given array si a VALUE-TYPE? */
2233
if(HAS_VALUETYPE_FLAG(arrayHeader))
2235
/* Retrieve the oversize offset */
2236
oversizeOffset = layoutInfos->typeSize *
2238
arrayHeader->dimSize;
2239
/* Given array isn't a VALUE-TYPE */
2243
/* Retrieve the IR type associated with this array */
2244
irType = get_IR_type_from_ILType(system->type_checker, layoutInfos->type, system->binaries);
2246
/* retrieve the slot size */
2247
slotSize = get_size_from_IRType(irType);
2249
/* Evaluate the oversize offset */
2250
oversizeOffset = slotSize * arrayHeader->rank *
2251
arrayHeader->dimSize;
2254
/* Given object is a real object */
2257
/* Given object is STATIC */
2258
if(HAS_STATIC_FLAG(objectHeader))
2260
/* Retrieve the oversize offset */
2261
staticLayoutInfos = (ILLayoutStatic*) objectHeader->layoutInfos;
2262
assert(staticLayoutInfos != NULL);
2263
oversizeOffset = staticLayoutInfos->typeSize;
2265
/* Given object is a "normal" object */
2268
/* Retrive the oversize offset */
2269
layoutInfos = (ILLayout*) objectHeader->layoutInfos;
2270
assert(layoutInfos != NULL);
2271
oversizeOffset = layoutInfos->typeSize;
2275
/* Return the offset */
2276
return oversizeOffset;
2279
/* Get object oversize area address */
2280
static void* gci_fetchOverSize(void* object)
2282
return object + gci_fetchOverSizeOffset(object);
2285
/* Get object IL type */
2286
static ILClassID gci_getType(void* object)
2289
t_objectHeader* objectHeader;
2291
/* Object layout infos */
2292
ILLayout* layoutInfos;
2295
assert(object != NULL);
2297
/* Retrieve the pointer to the header of the object */
2298
objectHeader = GET_OBJECT_HEADER(object);
2300
/* Retrieve the pointer to the layout informations */
2301
layoutInfos = objectHeader->layoutInfos;
2303
/* Return the classID of the current object */
2304
return layoutInfos->type->ID;
2307
static JITINT32 gci_getTypeSize(void * object)
2308
{ /* Given object type */
2311
ILLayout* layoutInfos;
2312
ILLayoutStatic* staticInfos;
2314
ILLayout_manager* layoutManager;
2316
/* Get all we need */
2317
system = getSystem(NULL);
2318
layoutManager = system->layout_manager;
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);
2326
/* We are creating a normal instance */
2327
if(!gci_isStatic(object))
2328
{ layoutInfos = layoutManager->layoutType(layoutManager, &type);
2329
typeSize = layoutInfos->typeSize;
2332
{ staticInfos = layoutManager->layoutStaticType(layoutManager, &type);
2333
typeSize = staticInfos->typeSize;
2339
void setup_garbage_collector_interaction(t_system* system)
2341
/* printObject parameters */
2342
jit_type_t printObjectParams[2];
2344
/* printArray parameters */
2345
jit_type_t printArrayParams[2];
2347
/* isSubtype parameters */
2348
jit_type_t isSubtypeParams[3];
2350
/* Other functions parameters */
2351
jit_type_t params[4];
2353
/* System garbage collector */
2354
t_running_garbage_collector* garbageCollector;
2357
assert(system != NULL);
2360
/* Initialize the internal garbage collector */
2362
#endif /* INTERNAL_GC */
2364
/* Get garbage collector */
2365
garbageCollector = &(system->garbage_collectors.gc);
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);
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);
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);
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,
2393
/* Create the allocPermanentObject signature */
2394
garbageCollector->signAllocPermanentObject =
2395
garbageCollector->signAllocObject;
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,
2406
/* Create the allocStaticObject signature */
2407
garbageCollector->signAllocStaticObject =
2408
garbageCollector->signAllocObject;
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,
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,
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,
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,
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;
2479
/* Initialize the rootSets */
2481
if(GC_NEEDS_ROOTSET(garbageCollector->gc_plugin)){
2482
rootSets = xanHashTableNew(DEFAULT_THREAD_NUMBER, JITFALSE, allocFunction, dynamicReallocFunction, freeFunction, NULL, pthread_equal);
2488
/* Create a new array that stores element of given type */
2489
static void* gci_createArray(ILType* type, JITBOOLEAN isCollectable, JITUINT32 rank, JITUINT32 size) {
2493
/* System layout manager */
2494
ILLayout_manager* layoutManager;
2496
/* Current garbage collector */
2497
t_garbage_collector_plugin* garbageCollector;
2500
t_type_analyzer* typeAnalyzer;
2502
/* Array global size without oversize */
2503
JITUINT32 arraySize;
2505
/* Array total size */
2506
JITUINT32 overallSize;
2508
/* Array layout info */
2509
ILLayout* layoutInfos;
2510
ILLayout* arrayLayoutInfos;
2512
/* Pointer to new array instance */
2515
/* Array element size */
2518
/* New instance header */
2519
t_arrayHeader* header;
2521
/* Enabled if the new array contains basic types (int, long, ...) */
2522
JITBOOLEAN isValueType;
2527
assert(type != NULL);
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;
2535
PDEBUG("GC: createArray: START\n");
2537
/* Fetch the CIL type of System.Array */
2538
(system->arrayManager).fillILArrayType(&arrayType);
2539
assert(arrayType.ID != NULL);
2540
assert(arrayType.binary != NULL);
2542
/* Fetch the layout of the System.Array type */
2543
arrayLayoutInfos = layoutManager->layoutType(layoutManager, &arrayType);
2544
assert(arrayLayoutInfos != NULL);
2546
/* Retrieve the IRType from the ILType */
2547
layoutInfos = layoutManager->layoutType(layoutManager, type);
2549
/* Set the slot size for the array */
2550
isValueType = typeAnalyzer->isValueType(typeAnalyzer, layoutInfos->type, system->binaries);
2552
slotSize = layoutInfos->typeSize;
2554
slotSize = get_size_from_IRType(IRMPOINTER);
2557
/* Set the array size */
2558
arraySize = slotSize * rank * size;
2560
/* Retrieve the overall size */
2561
overallSize = HEADER_FIXED_SIZE + arraySize + sizeof(JITNUINT);
2564
* An array can't have 0 fields: set at least an oversize of
2565
* sizeof(IRMPOINTER)
2567
if(overallSize == HEADER_FIXED_SIZE){
2568
overallSize += sizeof(IRMPOINTER);
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);
2578
array = garbageCollector->allocObject(overallSize);
2580
/* Check if the garbage collector has called the getRootSet method */
2581
if(rootSetList != NULL) {
2582
rootSetList->destroyList(rootSetList);
2586
/* Check if the memory is finished */
2588
jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
2589
print_err("createArray: ERROR = Libjit does not work as "
2595
/* Get array header */
2596
header = (t_arrayHeader*) array;
2597
assert(header != NULL);
2599
/* Set the IS_ARRAY flag */
2600
header->flags |= IS_ARRAY;
2602
/* Set the IS_COLLECTABLE flag */
2604
header->flags |= IS_COLLECTABLE;
2607
/* Set the IS_VALUETYPE flag */
2609
header->flags |= IS_VALUETYPE;
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;
2619
/* Initialize object lock and condition variable */
2620
ILJITMonitorInit(&header->monitor);
2622
PDEBUG("GC: createArray: EXIT\n");
2624
/* Normalize addres to IR machine format (without header) */
2625
array += HEADER_FIXED_SIZE;
2626
assert(array != NULL);
2628
/* Return the instance just created */
2632
/* Create a new instance of given type */
2633
static void* gci_createInstance(ILType* type, JITUINT32 overSize,
2634
JITBOOLEAN isCollectable,
2635
JITBOOLEAN isStatic)
2637
/* The new instance */
2640
/* The total memory we need to alloc given object */
2641
JITUINT32 overallSize;
2643
/* Given type basic size, without header and oversize */
2646
/* Given type info, if we alloc in non static mode */
2647
ILLayout* layoutInfos;
2649
/* Given type info, if we alloc in static mode */
2650
ILLayoutStatic* staticInfos;
2655
/* System layout manager */
2656
ILLayout_manager* layoutManager;
2658
/* Current running garbage collector */
2659
t_garbage_collector_plugin* garbageCollector;
2661
/* New instance header */
2662
t_objectHeader* header;
2665
assert(type != NULL);
2666
PDEBUG("GC: createInstance: Start\n");
2668
/* Initialize the variables */
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);
2681
/* Retrieve the layout infos for the specified type */
2682
PDEBUG("GC: createInstance: Retrieve the layout informations\n");
2684
/* We are creating a normal instance */
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;
2692
/* We are creating a static instance */
2695
/* Retrieve the typeSize of the instance */
2696
staticInfos = layoutManager->layoutStaticType(layoutManager,
2698
typeSize = staticInfos->typeSize;
2701
/* Call allocObject on GC */
2702
PDEBUG("GC: createInstance: Call the GC to fetch the memory for "
2703
"the new instance\n");
2705
overallSize = HEADER_FIXED_SIZE + typeSize + overSize;
2706
object = garbageCollector->allocObject(overallSize);
2708
/* Check if the garbage collector has called the getRootSet method */
2709
if(rootSetList != NULL) {
2710
rootSetList->destroyList(rootSetList);
2714
PDEBUG("GC: createInstance: Write the header of the new object\n");
2716
/* Ok, the garbage collector gave us the needed memory */
2719
/* Erase the object memory */
2720
memset(object, 0, overallSize);
2722
/* Get object header */
2723
header = (t_objectHeader*) object;
2727
header->flags |= IS_COLLECTABLE;
2729
header->flags |= IS_STATIC;
2731
/* Save layout info, normal mode */
2732
if(layoutInfos != NULL) {
2733
header->virtualTable = layoutInfos->virtualTable;
2734
header->layoutInfos = layoutInfos;
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);
2740
/* Save static layout info into object header */
2742
header->layoutInfos = staticInfos;
2744
/* Using the default object as a matrix for the real instance */
2746
assert(staticInfos->initialized_obj != NULL);
2747
memcpy(object+HEADER_FIXED_SIZE,
2748
staticInfos->initialized_obj, typeSize);
2751
assert(header->layoutInfos != NULL);
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);
2759
/* Initialize object lock and condition variable */
2760
ILJITMonitorInit(&header->monitor);
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);
2769
/* Normalize address to IR machine format (remove header) */
2770
object += HEADER_FIXED_SIZE;
2772
/* Return the instance just created */
2773
PDEBUG("GC: createInstance: Exit\n");
2777
/* Print given array */
2778
static void gci_printArray(void* array, char* prefix) {
2780
/* Check pointers */
2781
assert(prefix != NULL);
2783
/* Try to print a NULL array? Do nothing */
2784
if (array == NULL) {
2785
PDEBUG("GC_INTERACTIONS: printArray: WARNING! array is NULL \n");
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);
2795
/* Check if given object class is subtype of given class identifier */
2796
static JITBOOLEAN gci_isSubtype(t_system* system, void* object,
2799
/* Given object type */
2802
/* Garbage collector structure */
2803
t_running_garbage_collector garbageCollector;
2806
t_type_analyzer* typeAnalyzer;
2809
assert(classID != NULL);
2810
assert(system != NULL);
2811
assert(object != NULL);
2813
/* Initialize the variables */
2814
garbageCollector = system->garbage_collectors.gc;
2815
typeAnalyzer = system->type_checker->type_analyzer;
2817
/* Fetch the binary */
2818
objectType.binary = (t_binary_information*) garbageCollector.getBinary(object);
2820
/* Fetch the type */
2821
objectType.ID = (system->garbage_collectors).gc.getType(object);
2823
/* Verify if objectType is subtype of ``classID'' */
2824
return typeAnalyzer->_isSubtype(typeAnalyzer, &objectType, classID, system->binaries);
2827
/* Get size of a given array slot */
2828
JITUINT32 getArraySlotSize(void* array)
2830
/* Array slot IR type */
2833
/* Given array slot size */
2834
JITUINT32 arraySlotSize;
2836
/* Given array header */
2837
t_arrayHeader* header;
2839
/* Array layout info */
2840
ILLayout* layoutInfos;
2843
assert(array != NULL);
2846
gci_printObject(array, "[ARRAY]");
2847
#endif /* PRINTDEBUG */
2849
/* Retrieve the IR type associated with the current slot type */
2850
irType = gci_getArraySlotIRType(array);
2852
/* Array don't stores references */
2853
if((irType != IRVALUETYPE) && (irType != IRTYPEDREF))
2855
arraySlotSize = getIRSize(irType);
2857
/* Array stores references */
2860
/* Retrieve the array header */
2861
header = GET_ARRAY_HEADER(array);
2863
/* Get layout infos */
2864
layoutInfos = (ILLayout*) header->layoutInfos;
2867
arraySlotSize = layoutInfos->typeSize;
2870
return arraySlotSize;
2873
/* Create a new thread */
2874
static JITINT32 gci_threadCreate(pthread_t* thread,
2875
pthread_attr_t* attr,
2876
void* (*startRoutine)(void*),
2879
return pthread_create(thread, attr, startRoutine, arg);
2882
/* Add given root set to global one */
2883
static void gci_addRootSet(void*** rootSet, JITUINT32 size) {
2887
/* Current thread identifier */
2890
/* Current thread root set */
2891
t_root_sets* threadRootSet;
2893
t_garbage_collector_plugin* garbageCollector;
2896
assert(rootSet != NULL);
2898
PDEBUG("GC: addRootSet: Start\n");
2899
PDEBUG("GC: addRootSet: Size of root set to add = %u\n", size);
2901
/* Get garbage collector interface */
2902
garbageCollector = getSystem(NULL)->garbage_collectors.gc.gc_plugin;
2904
/* Check if the garbage collector has requested this kind of support */
2905
if(!GC_NEEDS_ROOTSET(garbageCollector)) {
2909
/* Get current thread root set */
2910
threadId = pthread_self();
2911
threadRootSet = rootSets->synchLookup(rootSets, (void *)threadId);
2914
if(threadRootSet == NULL) {
2915
threadRootSet = allocFunction(sizeof(t_root_sets));
2916
init_root_sets(threadRootSet);
2917
rootSets->synchInsert(rootSets, threadId, threadRootSet);
2919
assert(threadRootSet != NULL);
2922
threadRootSet->lock(threadRootSet);
2924
/* Add a new slot for the new root set */
2925
threadRootSet->addNewRootSet(threadRootSet);
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]);
2933
PDEBUG("GC: addRootSet: Root set top = %u\n", threadRootSet->top);
2935
assert(threadRootSet->top > 0);
2938
/* Print the root sets */
2939
gci_printRootSets(threadRootSet);
2940
#endif /* PRINTDEBUG */
2942
/* Unlock root set */
2943
threadRootSet->unlock(threadRootSet);
2945
PDEBUG("GC: addRootSet: Exit\n");
2947
/* Return from routine */
2951
/* Remove last added root set from root set stack */
2952
static void gci_popLastRootSet(void)
2954
/* Current thread root set */
2955
t_root_sets* threadRootSet;
2956
t_garbage_collector_plugin* garbageCollector;
2958
PDEBUG("GC: popLastRootSet: Start\n");
2960
/* Fetch running garbage collector */
2961
garbageCollector = getSystem(NULL)->garbage_collectors.gc.gc_plugin;
2963
/* Check if the garbage collector has request this kind of support */
2964
if(!GC_NEEDS_ROOTSET(garbageCollector)) {
2968
/* Get current thread root set */
2969
threadRootSet = rootSets->synchLookup(rootSets, pthread_self());
2970
assert(threadRootSet != NULL);
2973
threadRootSet->lock(threadRootSet);
2975
/* Pop the last root set */
2976
threadRootSet->popLastRootSet(threadRootSet);
2979
/* Print the root sets */
2980
gci_printRootSets(threadRootSet);
2981
#endif /* PRINTDEBUG */
2983
/* Unlock root set */
2984
threadRootSet->unlock(threadRootSet);
2986
PDEBUG("GC: popLastRootSet: Exit\n");
2992
/* Print given root set contents */
2993
static void gci_printRootSets(t_root_sets* rootSets)
2998
/* Object reference */
2999
void** objectReference;
3002
assert(rootSets != NULL);
3004
PDEBUG("GC: printRootSets: Start\n");
3005
PDEBUG("GC: printRootSets: -----------------------START-----------"
3006
"--------------------------------\n");
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",
3016
GET_OBJECT_HEADER(*objectReference));
3018
PDEBUG("GC: printRootSets: -----------------------END-------------"
3019
"--------------------------------\n");
3020
PDEBUG("GC: printRootSets: Exit\n");
3026
/* Remove given thread root set from the active ones */
3027
static void gci_threadExit(pthread_t threadId) {
3029
/* The root set to delete */
3030
t_root_sets* threadRootSet;
3032
/* Check if there is a root set */
3033
if (rootSets == NULL) return ;
3035
/* Lock by hand the table since we must do several operations */
3036
rootSets->lock(rootSets);
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);
3045
/* All its done, exit from critical section */
3046
rootSets->unlock(rootSets);
3050
/* Call Finalize method on given object */
3051
void callFinalizer(void* object) {
3053
/* Given object header */
3054
t_objectHeader* header;
3056
/* Given object layout infos */
3059
/* The Finalize method */
3062
/* Used to translate method */
3063
TranslationPipeline* pipeliner;
3065
/* Finalize arguments */
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;
3073
/* Retrive Finalize method */
3074
layout = (ILLayout*) header->layoutInfos;
3075
finalize = layout->finalize;
3077
if (finalize != NULL){
3080
pipeliner = getSystem(NULL)->pipeliner;
3081
pipeliner->synchInsertMethod(pipeliner, finalize, MAX_METHOD_PRIORITY);
3083
/* And at last run */
3085
jit_function_apply(finalize->getJITFunction(finalize), args, NULL);
3087
/* Free synchronization resources */
3088
ILJITMonitorDestroy(&header->monitor);
3093
static JITBOOLEAN gci_lockObject(void* object, JITINT32 timeout) {
3096
t_objectHeader* header;
3098
/* Whether lock has been acquired */
3099
JITBOOLEAN lockAcquired;
3101
/* Get object header */
3102
header = GET_OBJECT_HEADER(object);
3105
lockAcquired = ILJITMonitorLock(&header->monitor, timeout);
3107
return lockAcquired;
3112
static void gci_unlockObject(void* object) {
3115
t_objectHeader* header;
3117
/* Get object header */
3118
header = GET_OBJECT_HEADER(object);
3120
/* Unlock the object */
3121
ILJITMonitorUnlock(&header->monitor);
3125
/* Wait for pulse signal on object */
3126
static JITBOOLEAN gci_waitForPulse(void* object, JITINT32 timeout) {
3129
t_objectHeader* header;
3131
/* Set to JITTRUE if pulse signal is detected before timeout */
3132
JITBOOLEAN pulseOccursBeforeTimeout;
3134
/* Get object header */
3135
header = GET_OBJECT_HEADER(object);
3137
/* Wait for signals */
3138
pulseOccursBeforeTimeout = ILJITMonitorWaitForPulse(&header->monitor,
3141
return pulseOccursBeforeTimeout;
3146
static void gci_signalPulse(void* object) {
3148
/* Given object header */
3149
t_objectHeader* header;
3151
/* Get the header */
3152
header = GET_OBJECT_HEADER(object);
3154
/* Signal the pulse */
3155
ILJITMonitorSignalPulse(&header->monitor);
3159
/* Signal pulse all */
3160
static void gci_signalPulseAll(void* object) {
3162
/* Given object header */
3163
t_objectHeader* header;
3165
/* Get the header */
3166
header = GET_OBJECT_HEADER(object);
3168
/* Signal the pulse all */
3169
ILJITMonitorSignalPulseAll(&header->monitor);