5b72a6b053bb47d2445438ec6f6eccfda160ebc8
1 /* This file is part of NIT ( http://www.nitlanguage.org ).
3 * Copyright 2009 Julien Chevalier <chevjulien@gmail.com>
5 * This file is free software, which comes along with NIT. This software is
6 * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 * is kept unaltered, and a notification of the changes is added.
10 * You are allowed to redistribute it and sell it, alone or is a part of
18 heapActive
= malloc(sizeof(heap
));
19 heapInactive
= malloc(sizeof(heap
));
21 heapActive
->heapPointer
= malloc(HEAP_ACTIVE_SIZE_MIN
);
22 heapInactive
->heapPointer
= malloc(HEAP_ACTIVE_SIZE_MIN
);
24 if (heapActive
->heapPointer
==NULL
) exit(1);
25 if (heapInactive
->heapPointer
==NULL
) exit(1);
27 heapActive
->size
= HEAP_ACTIVE_SIZE_MIN
;
28 heapInactive
->size
= HEAP_ACTIVE_SIZE_MIN
;
30 allocationPointer
= heapActive
->heapPointer
;
32 evacuationPointer
= heapInactive
->heapPointer
;
33 scavengingPointer
= evacuationPointer
;
35 GC_List_Init(&staticObjects
);
38 val_t
GC_evacuation(obj_t object
){
42 Nit_NativeArray array
;
45 assert(ISOBJ(object
) && !ISNULL(object
));
46 if ( GET_MARKBIT(object
) != (bigint
)0) {
47 newAdress
= REMOVE_MARKBIT((bigint
)((object
)->vft
));
49 newAdress
= (val_t
)evacuationPointer
;
50 if (OBJ_IS_ARRAY(object
)) {
51 array
= (Nit_NativeArray
) object
;
52 size
= sizeof(struct Nit_NativeArray
) + ((array
->size
- 1) * sizeof(val_t
));
53 memcpy((void *)evacuationPointer
, (array
), size
);
54 (array
)->vft
= (classtable_elt_t
*)evacuationPointer
;
55 }else if(IS_BOX(object
)){
56 box
= (BOX_struct
)object
;
57 size
= sizeof(struct TBOX_struct
);
58 memcpy((void *)evacuationPointer
, object
, size
);
59 box
->vft
= (classtable_elt_t
*)evacuationPointer
;
61 objectSize
= (bigint
)((object
)[0].vft
[1].i
);
62 size
= (objectSize
) * sizeof(val_t
);
63 memcpy((void *)evacuationPointer
, object
, size
);
64 (object
)[0].vft
= (classtable_elt_t
*)evacuationPointer
;
67 evacuationPointer
+= size
;
74 obj_t object
= (obj_t
)scavengingPointer
;
75 obj_t
* object2
= (obj_t
*)&scavengingPointer
;
78 obj_t referencedObject
;
80 Nit_NativeArray
* array
;
82 if ( IS_BOX(object
)) {
83 size
= sizeof(struct TBOX_struct
);
85 array
= (Nit_NativeArray
*)&scavengingPointer
;
86 if (OBJ_IS_ARRAY((obj_t
)*array
)) {
87 size
= sizeof(struct Nit_NativeArray
) + (((*array
)->size
- 1) * sizeof(val_t
));
88 for (i
= 0; i
< (*array
)->size
; i
++) {
89 referencedObject
= (obj_t
)((*array
)->val
[i
]);
90 if (!ISNULL(referencedObject
) && ISOBJ(referencedObject
)) {
91 (*array
)->val
[i
] = (bigint
)GC_evacuation(referencedObject
);
95 objectSize
= (bigint
)((object
)->vft
[1].i
);
96 size
= (objectSize
) * sizeof(val_t
);
97 for (i
= 2; i
< objectSize
; i
++) {
98 referencedObject
= (obj_t
)(object
[i
].objectSize
);
99 if (!ISNULL(referencedObject
) && ISOBJ(referencedObject
)) {
100 ((object
)[i
].objectSize
) = (bigint
)GC_evacuation(referencedObject
);
105 scavengingPointer
+= size
;
113 struct trace_t
* frame
= tracehead
;
114 GC_static_object
* staticObject
= staticObjects
.top
;
118 evacuationPointer
= heapInactive
->heapPointer
;
119 scavengingPointer
= heapInactive
->heapPointer
;
120 for (i
= 0; i
< staticObjects
.size
; i
++) {
121 object
= *(val_t
*)(staticObject
->pointer
);
122 if(!ISNULL(object
) && ISOBJ(object
)){
123 *(staticObject
->pointer
) = (val_t
)GC_evacuation((obj_t
)object
);
125 staticObject
= staticObject
->next
;
127 while (frame
!= NULL
) {
128 pointers
= frame
->REG_pointer
;
129 for (j
= 0; j
< frame
->REG_size
; j
++) {
130 object
= (val_t
)(pointers
[j
]);
131 if(!ISNULL(object
) && ISOBJ(object
)){
132 pointers
[j
] = (val_t
*)GC_evacuation((obj_t
)object
);
135 if (frame
== frame
->prev
) break;
138 while ( evacuationPointer
!= scavengingPointer
) {
142 /* pour tests seulement, pas necessaire */
143 memset((void *)heapActive
->heapPointer
, 0, heapActive
->size
);
144 allocationPointer
= evacuationPointer
;
146 /* inverse le tas actif et le tas inactif */
147 tempPointer
= heapActive
;
148 heapActive
= heapInactive
;
149 heapInactive
= tempPointer
;
151 heapActiveUsedSize
= (int)allocationPointer
- (int)heapActive
->heapPointer
;
154 void GC_set_heap_size(size_t newHeapSize
){
155 free(heapInactive
->heapPointer
);
156 heapInactive
->heapPointer
= malloc(newHeapSize
);
157 if(heapInactive
->heapPointer
== NULL
) {
160 heapInactive
->size
= newHeapSize
;
161 memset(heapInactive
->heapPointer
, 0, newHeapSize
);
164 void GC_detect_memory_needs( size_t size
) {
165 if ( size
> (heapActive
->size
- heapActiveUsedSize
)) {
167 if (heapActive
->size
- heapActiveUsedSize
> heapActive
->size
/ 2 && heapActive
->size
* 3 / 4 > HEAP_ACTIVE_SIZE_MIN
){
168 GC_set_heap_size(heapActive
->size
* 3 / 4);
170 GC_set_heap_size(heapActive
->size
);
173 if ( size
> (heapActive
->size
- heapActiveUsedSize
)) {
174 int try_size
= heapInactive
->size
* 2;
175 while (size
> (try_size
- heapActiveUsedSize
)){
178 GC_set_heap_size(try_size
);
180 GC_set_heap_size(heapActive
->size
);
184 void *Nit_gc_malloc( size_t size
) {
187 GC_detect_memory_needs(size
);
189 result
= allocationPointer
;
190 heapActiveUsedSize
+= size
;
191 allocationPointer
+= size
;
196 void GC_add_static_object(val_t
* pointer
){
197 GC_List_Push(&staticObjects
, pointer
);