source: src/examples/gc_no_raii/src/internal/collector.c @ bee4283

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since bee4283 was 16cfd8c, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

1 error left

  • Property mode set to 100644
File size: 3.3 KB
Line 
1#include "collector.h"
2
3#ifdef __cforall
4extern "C" {
5#endif
6#include <string.h>
7#ifdef __cforall
8}
9#endif
10
11#include "state.h"
12#include "gcpointers.h"
13#include "memory_pool.h"
14
15void* gc_finish_alloc_block(void* block, size_t actual_size, size_t target_size);
16void gc_assign_reference(void** ref, gc_object_header* ptr);
17
18gcpointer_t** gc_find_previous_ref(gcpointer_t* target)
19{
20        if(!(target)) return NULL;
21
22        bool managed = gc_is_managed(target);
23        gc_object_header* obj = gc_get_object_ptr((void*)target->ptr);
24
25        check(gc_is_valide(obj));
26
27        gcpointer_t** prev_next_ptr = managed ? &obj->type_chain : &obj->root_chain;
28        while((*prev_next_ptr) && (*prev_next_ptr) != target)
29        {
30                prev_next_ptr = &(*prev_next_ptr)->next;
31        }
32
33        return prev_next_ptr;
34}
35
36void* gc_allocate(size_t target_size)
37{
38        size_t size = gc_compute_size(target_size + sizeof(gc_object_header));
39
40        check(size < POOL_SIZE_BYTES);
41
42        void* block = NULL;
43        gc_state* gc = gc_get_state();
44
45        if((intptr_t)(block = gc_try_allocate(gc, size))) return gc_finish_alloc_block(block, size, target_size);
46
47        gc_collect(gc);
48
49        if((intptr_t)(block = gc_try_allocate(gc, size))) return gc_finish_alloc_block(block, size, target_size);
50
51        gc_allocate_pool(gc);
52
53        if((intptr_t)(block = gc_try_allocate(gc, size))) return gc_finish_alloc_block(block, size, target_size);
54
55        checkf(false, "ERROR: allocation in new pool failed");
56
57        return NULL;
58}
59
60void* gc_finish_alloc_block(void* block, size_t actual_size, size_t target_size)
61{
62        void* data = (void*)(((intptr_t)block) + sizeof(gc_object_header));
63        void* header = block;
64
65        check(((intptr_t)data) > ((intptr_t)block));
66        check(((intptr_t)data) >= ((intptr_t)header));
67        check(is_aligned(data));
68        check(((intptr_t)data) + target_size <= ((intptr_t)block) + actual_size);
69
70        gc_object_header* obj = placement_ctor(header, actual_size);
71
72        (void)obj; //remove unsused warning since this is for debug
73        check(obj == get_object_ptr(data));
74
75        gc_register_allocation(gc_get_state(), actual_size);
76
77        return data;
78}
79
80void gc_process_reference(void** ref, worklist_t* worklist)
81{
82        check(!gc_is_in_heap(gc_get_state(), ref));
83
84        gc_object_header* ptr = gc_get_object_ptr(*ref);
85        if(ptr)
86        {
87                if(!ptr->is_forwarded)
88                {
89                        gc_copy_object(ptr);
90
91                        gc_scan_object(ptr->forward, worklist);
92
93                        gc_assign_reference(ref, ptr->forward);
94                }
95                else
96                {
97                        //duplication to help debug
98                        gc_assign_reference(ref, ptr->forward);
99                }
100        }
101}
102
103void gc_assign_reference(void** ref, gc_object_header* ptr)
104{
105        void* address = (void*)(((intptr_t)ptr) + sizeof(gc_object_header));
106
107        gc_write_aligned_ptr(ref, address);
108}
109
110gc_object_header* gc_copy_object(gc_object_header* ptr)
111{
112        check(!ptr->forward);
113        check(!ptr->is_forwarded);
114        check(gc_is_from_space(gc_pool_of(ptr)));
115
116        gc_memory_pool* pool = gc_pool_of(ptr)->mirror;
117
118        void* new_block = gc_pool_allocate(pool, ptr->size, true);
119
120        memcpy(new_block, ptr, ptr->size);
121
122        gc_object_header* fwd_ptr = placement_copy_ctor(new_block, ptr);
123
124        ptr->forward = fwd_ptr;
125        ptr->is_forwarded = true;
126
127        return fwd_ptr;
128}
129
130void gc_scan_object(gc_object_header* object, worklist_t* worklist)
131{
132        gcpointer_t* field = object->type_chain;
133        while(field)
134        {
135                check(((intptr_t)field) > ((intptr_t)object));
136                check(((intptr_t)field) < ((intptr_t)((intptr_t)object) + object->size));
137
138                check(gc_is_in_to_space(gc_get_state(), &type->ptr));
139
140                intptr_t* ref = &field->ptr;
141                push_back(worklist, ref);
142
143                field = field->next;
144        }
145}
Note: See TracBrowser for help on using the repository browser.