source: src/examples/gc_no_raii/src/internal/collector.c @ 385c130

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglergc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 385c130 was 385c130, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

pre merge

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