Ignore:
Timestamp:
Apr 19, 2016, 1:19:25 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
9026b4b
Parents:
356bb95
Message:

pre merge

Location:
src/examples/gc_no_raii/src/internal
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/examples/gc_no_raii/src/internal/collector.c

    r356bb95 r385c130  
    88#include <fstream>
    99
    10 // #include "state.h"
    11 // #include "gcpointers.h"
    12 // #include "memory_pool.h"
     10#include "state.h"
     11#include "gcpointers.h"
     12#include "memory_pool.h"
    1313
    14 // void* gc_finish_alloc_block(void* block, size_t actual_size, size_t target_size);
    15 // void gc_assign_reference(void** ref, gc_object_header* ptr);
     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);
    1616
    17 // gcpointer_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 // }
     17gcpointer_t** gc_find_previous_ref(gcpointer_t* target)
     18{
     19        if(!(target)) return NULL;
    3420
    35 // void* 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 //      ofstream_stderr() | "ERROR: allocation in new pool failed" | endl;
    55 //      abort();
    56 //
    57 //      return NULL;
    58 // }
    59 //
    60 // void* 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 = gc_object_header_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 //
    80 // void 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 //
    103 // void 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 //
    110 // gc_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 = gc_object_header_placement_copy_ctor(new_block, ptr);
    123 //
    124 //      ptr->forward = fwd_ptr;
    125 //      ptr->is_forwarded = true;
    126 //
    127 //      return fwd_ptr;
    128 // }
    129 //
    130 // void 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 //              push_back(worklist, &field->ptr);
    141 //
    142 //              field = field->next;
    143 //      }
    144 // }
     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}
  • src/examples/gc_no_raii/src/internal/collector.h

    r356bb95 r385c130  
    44#include <stdint.h>
    55
    6 // #include "tools.h"
     6#include "tools.h"
    77//
    8 // #include "gcpointers.h"
     8#include "gcpointers.h"
    99#include "state.h"
    1010#include "internal/gc_tools.h"
    11 // #include "internal/globals.h"
    12 // #include "internal/object_header.h"
    13 // #include "internal/state.h"
     11#include "internal/globals.h"
     12#include "internal/object_header.h"
     13#include "internal/state.h"
    1414#include "tools/worklist.h"
    1515
     
    1919}
    2020
    21 // inline gc_object_header* gc_get_object_ptr(void* ptr)
    22 // {
    23 //      void* clean = gc_get_aligned_ptr(ptr);
    24 //      return ((gc_object_header*)clean) - 1;
    25 // }
     21inline gc_object_header* gc_get_object_ptr(void* ptr)
     22{
     23        void* clean = gc_get_aligned_ptr(ptr);
     24        return ((gc_object_header*)clean) - 1;
     25}
    2626
    27 // inline gc_memory_pool* gc_pool_of(void* address)
    28 // {
    29 //      return (struct gc_memory_pool*)(((intptr_t)address) & POOL_PTR_MASK);
    30 // }
    31 //
    32 // inline void gc_conditional_collect()
    33 // {
    34 //      if(gc_needs_collect(gc_get_state()))
    35 //      {
    36 //              gc_collect(gc_get_state());
    37 //      }
    38 // }
    39 //
    40 // gcpointer_t** gc_find_previous_ref(gcpointer_t* target);
    41 //
    42 // void* gc_allocate(size_t size);
    43 //
    44 // void gc_process_reference(void** ref, worklist_t* worklist);
    45 //
    46 // struct gc_object_header* gc_copy_object(struct gc_object_header* ptr);
    47 //
    48 // void gc_scan_object(struct gc_object_header* object, worklist_t* worklist);
     27inline struct gc_memory_pool* gc_pool_of(void* address)
     28{
     29        return (struct gc_memory_pool*)(((intptr_t)address) & POOL_PTR_MASK);
     30}
     31
     32inline void gc_conditional_collect()
     33{
     34        if(gc_needs_collect(gc_get_state()))
     35        {
     36                gc_collect(gc_get_state());
     37        }
     38}
     39
     40gcpointer_t** gc_find_previous_ref(gcpointer_t* target);
     41
     42void* gc_allocate(size_t size);
     43
     44void gc_process_reference(void** ref, worklist_t* worklist);
     45
     46struct gc_object_header* gc_copy_object(struct gc_object_header* ptr);
     47
     48void gc_scan_object(struct gc_object_header* object, worklist_t* worklist);
  • src/examples/gc_no_raii/src/internal/gc_tools.h

    r356bb95 r385c130  
    1212}
    1313
    14 // inline void* gc_get_aligned_ptr(void* address)
    15 // {
    16 //      return (void*)(((intptr_t)address) & (OBJECT_PTR_MASK));
    17 // }
    18 //
    19 // inline void* gc_write_aligned_ptr(void** reference, void* address)
    20 // {
    21 //      size_t ref_last_bits = ((intptr_t)*reference) & (~OBJECT_PTR_MASK);
    22 //
    23 //       size_t new_val = ((intptr_t)address) & OBJECT_PTR_MASK;
    24 //
    25 //       (*reference) = (void*)(new_val | ref_last_bits);
    26 //
    27 //      return *reference;
    28 // }
    29 //
    30 // inline size_t gc_compute_size(size_t size)
    31 // {
    32 //      size_t word_size = ((size - 1) / OBJECT_ALLIGNMENT) + 1;
    33 //      size_t ret = word_size * OBJECT_ALLIGNMENT;
    34 //
    35 //      check(ret >= size);
    36 //      check((ret % OBJECT_ALLIGNMENT) == 0);
    37 //      check( ((size % OBJECT_ALLIGNMENT) != 0) || (ret == size) );
    38 //
    39 //      return ret;
    40 // }
     14inline void* gc_get_aligned_ptr(void* address)
     15{
     16        return (void*)(((intptr_t)address) & (OBJECT_PTR_MASK));
     17}
     18
     19inline void* gc_write_aligned_ptr(void** reference, void* address)
     20{
     21        size_t ref_last_bits = ((intptr_t)*reference) & (~OBJECT_PTR_MASK);
     22
     23      size_t new_val = ((intptr_t)address) & OBJECT_PTR_MASK;
     24
     25      (*reference) = (void*)(new_val | ref_last_bits);
     26
     27        return *reference;
     28}
     29
     30inline size_t gc_compute_size(size_t size)
     31{
     32        size_t word_size = ((size - 1) / OBJECT_ALLIGNMENT) + 1;
     33        size_t ret = word_size * OBJECT_ALLIGNMENT;
     34
     35        check(ret >= size);
     36        check((ret % OBJECT_ALLIGNMENT) == 0);
     37        check( ((size % OBJECT_ALLIGNMENT) != 0) || (ret == size) );
     38
     39        return ret;
     40}
  • src/examples/gc_no_raii/src/internal/memory_pool.h

    r356bb95 r385c130  
    2424        uint8_t start_p[1];
    2525};
     26
     27void gc_memory_pool_ctor(gc_memory_pool *const this,
     28        size_t size,
     29        gc_memory_pool* next,
     30        gc_memory_pool* mirror,
     31     uint8_t type
     32        );
    2633
    2734struct gc_pool_object_iterator
     
    5865void gc_reset_pool(gc_memory_pool* pool);
    5966
     67inline size_t gc_pool_size_used(const gc_memory_pool* pool)
     68{
     69        return pool->free_p - pool->start_p;
     70}
     71
    6072inline size_t gc_pool_size_total(const gc_memory_pool* pool)
    6173{
  • src/examples/gc_no_raii/src/internal/state.c

    r356bb95 r385c130  
    11#include "state.h"
    22
    3 // #include <stdlib.h>
    4 //
    5 // //general purpouse includes
    6 // #include "tools.h"
    7 //
    8 // //platform abstraction includes
    9 // #include "allocate-pool.h"
    10 //
    11 // //gc internal includes
    12 // // #include "globals.h"
    13 // #include "memory_pool.h"
     3#include <stdlib.h>
     4
     5//general purpouse includes
     6#include "tools.h"
     7
     8//platform abstraction includes
     9#include "allocate-pool.h"
     10
     11//gc internal includes
     12#include "globals.h"
     13#include "memory_pool.h"
    1414// #include "memory_pool_iterator.h"
    15 // #include "object_header.h"
    16 //
    17 // void swap(gc_state* state);
    18 // void sweep_roots(worklist_t worklist);
    19 // void clear(gc_state* state);
    20 // void calc_usage(gc_state* state);
    21 //
    22 // #if DEBUG
    23 //      bool roots_match(gc_state* state);
    24 //      bool no_from_space_ref(gc_state* state);
    25 // #endif
    26 
    27 // void gc_state_ctor(gc_state* state)
    28 // {
    29 //      state->from_code = 0;
    30 //      state->to_space = NULL;
    31 //      state->from_space = NULL;
    32 //      state->total_space = 0;
    33 //      state->used_space = 0;
    34 //      // state->pools_table();
    35 //
    36 //      gc_allocate_pool(state);
    37 //
    38 //      state->is_initialized = true;
    39 // }
     15#include "object_header.h"
     16
     17void gc_state_swap(gc_state *const this);
     18void gc_state_sweep_roots(gc_state *const this, worklist_t* worklist);
     19void gc_state_clear(gc_state *const this);
     20void gc_state_calc_usage(gc_state *const this);
     21
     22#if DEBUG
     23        bool gc_state_roots_match(gc_state *const this);
     24        bool gc_state_no_from_space_ref(gc_state *const this);
     25#endif
     26
     27gc_state* gc_get_state()
     28{
     29        static gc_state s;
     30        if(!s.is_initialized) gc_state_ctor(&s);
     31        return &s;
     32}
     33
     34void gc_state_ctor(gc_state *const this)
     35{
     36        this->from_code = 0;
     37        this->to_space = NULL;
     38        this->from_space = NULL;
     39        this->total_space = 0;
     40        this->used_space = 0;
     41        // state->pools_table();
     42
     43        gc_allocate_pool(this);
     44
     45        this->is_initialized = true;
     46}
    4047
    4148// bool state::is_in_heap(void* address) const
     
    8693//      return NULL;
    8794// }
    88 //
    89 // void* state::try_allocate(size_t size)
    90 // {
    91 //      memory_pool* pool = from_space;
    92 //      while(pool)
    93 //      {
    94 //              if(pool->size_left() > size)
    95 //              {
    96 //                      return pool->allocate(size, true);
    97 //              }
    98 //              pool = pool->next();
    99 //      }
    100 //
    101 //      return nullptr;
    102 // }
    103 //
    104 // void state::allocate_pool()
    105 // {
    106 //      memory_pool* old_from_space = from_space;
    107 //       memory_pool* old_to_space = to_space;
    108 //
    109 //       from_space = reinterpret_cast<memory_pool*>(pal_allocPool(POOL_SIZE_BYTES, 1));
    110 //       to_space = reinterpret_cast<memory_pool*>(pal_allocPool(POOL_SIZE_BYTES, 1));
    111 //
    112 //       new (from_space) memory_pool(POOL_SIZE_BYTES, old_from_space, to_space, from_code);
    113 //       new (to_space) memory_pool(POOL_SIZE_BYTES, old_to_space, from_space, (~from_code) & 0x01);
    114 //
    115 //      total_space += from_space->size();
    116 //
    117 //      pools_table.push_back(from_space);
    118 //      pools_table.push_back(to_space);
    119 // }
    120 //
    121 // void state::collect()
    122 // {
    123 //      DEBUG("collecting");
    124 //      DEBUG("previous usage " << used_space << " / " << total_space);
    125 //
    126 //      std::vector<void**> worklist;
    127 //      sweep_roots(worklist);
    128 //
    129 //      while(!worklist.empty())
    130 //      {
    131 //              void** ref = worklist.back();
    132 //              worklist.pop_back();
    133 //              process_reference(ref, worklist);
    134 //      }
    135 //
    136 //      check(roots_match());
    137 //      check(no_from_space_ref());
    138 //
    139 //      swap();
    140 //
    141 //      calc_usage();
    142 //
    143 //      if(needs_collect()) allocate_pool();
    144 //
    145 //      DEBUG("done");
    146 // }
     95
     96void* gc_state_try_allocate(gc_state *const this, size_t size)
     97{
     98        gc_memory_pool* pool = this->from_space;
     99        while(pool != (gc_memory_pool*)0)
     100        {
     101                if(gc_pool_size_left(pool) > size)
     102                {
     103                        return gc_pool_allocate(pool, size, true);
     104                }
     105                pool = pool->next;
     106        }
     107
     108        return (void*)0;
     109}
     110
     111void gc_state_allocate_pool(gc_state *const this)
     112{
     113        gc_memory_pool* old_from_space = this->from_space;
     114      gc_memory_pool* old_to_space = this->to_space;
     115
     116      this->from_space = (gc_memory_pool*)(pal_allocPool(POOL_SIZE_BYTES, 1));
     117      this->to_space = (gc_memory_pool*)(pal_allocPool(POOL_SIZE_BYTES, 1));
     118
     119      gc_memory_pool_ctor(this->from_space, POOL_SIZE_BYTES, old_from_space, this->to_space,   this->from_code);
     120      gc_memory_pool_ctor(this->to_space,   POOL_SIZE_BYTES, old_to_space,   this->from_space, (~this->from_code) & 0x01);
     121
     122        this->total_space += gc_pool_size_used(this->from_space);
     123
     124        // pools_table.push_back(from_space);
     125        // pools_table.push_back(to_space);
     126}
     127
     128void gc_state_collect(gc_state *const this)
     129{
     130        // DEBUG("collecting");
     131        // DEBUG("previous usage " << this->used_space << " / " << this->total_space);
     132
     133        worklist_t worklist;
     134        // vector_ctor(&worklist);
     135        gc_state_sweep_roots(this, &worklist);
     136
     137        while(!empty(&worklist))
     138        {
     139                void** ref = back(&worklist);
     140                pop_back(&worklist);
     141                gc_state_process_reference(this, ref, &worklist);
     142        }
     143        //
     144        // check(gc_state_roots_match(this));
     145        // check(gc_state_no_from_space_ref(this));
     146        //
     147        // gc_state_swap(this);
     148        //
     149        // gc_state_calc_usage(this);
     150        //
     151        // if(gc_state_needs_collect(this)) gc_state_allocate_pool(this);
     152
     153        // DEBUG("done");
     154        // dtor(&worklist);
     155}
    147156//
    148157// void state::swap()
  • src/examples/gc_no_raii/src/internal/state.h

    r356bb95 r385c130  
    2222void gc_state_ctor(struct gc_state* state);
    2323
    24 static inline gc_state* gc_get_state()
    25 {
    26         static gc_state s;
    27         if(!s.is_initialized) gc_state_ctor(&s);
    28         return &s;
    29 }
     24gc_state* gc_get_state();
    3025
    3126inline bool gc_needs_collect(gc_state* state)
Note: See TracChangeset for help on using the changeset viewer.