History

Move some basic offset functions to header files for inlining ease Replace enum_pointer_field functions with custom implementations - GC now has custom implementation - other implementations use template<> version Fix misuse of shared_ptr<type_descriptor_t> in various built-in types Observed 5 - 8 % improvement in GC for compiler scenario.

arr committed 9 years ago

Commit cd2748b1 parent 3dd1c8210 files · +115 −160Browse files

Showing the changes to src/include (2 of 10 files). Show all

Unified · Split

2 files
  1. src/include/runtime.h +15 −3
  2. src/include/vm_memory.h +31 −17
src/include/runtime.h+15−3
@@ -98,7 +98,14 @@ namespace disvm · 97 unmodified lines
98 98
99 static vm_alloc_t *allocate(std::shared_ptr<const type_descriptor_t> td);99 static vm_alloc_t *allocate(std::shared_ptr<const type_descriptor_t> td);
100 static vm_alloc_t *copy(const vm_alloc_t &other);100 static vm_alloc_t *copy(const vm_alloc_t &other);
101 static vm_alloc_t *from_allocation(pointer_t allocation);101
102 static vm_alloc_t *from_allocation(pointer_t allocation)
103 {
104 if (allocation == nullptr)
105 return nullptr;
106
107 return reinterpret_cast<vm_alloc_t *>(reinterpret_cast<uint8_t *>(allocation) - sizeof(vm_alloc_t));
108 }
102 109
103 template <typename T>110 template <typename T>
104 static T *from_allocation(pointer_t allocation)111 static T *from_allocation(pointer_t allocation)
@@ -125,7 +132,12 @@ namespace disvm · 20 unmodified lines
125 pointer_t gc_reserved;132 pointer_t gc_reserved;
126 133
127 public:134 public:
128 pointer_t get_allocation() const;135 pointer_t get_allocation() const
136 {
137 // Remove const on the this pointer so the offset can be computed.
138 auto non_const_this = const_cast<vm_alloc_t *>(this);
139 return reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(non_const_this) + sizeof(vm_alloc_t));
140 }
129 141
130 template <typename T>142 template <typename T>
131 T *get_allocation() const143 T *get_allocation() const
@@ -638,7 +650,7 @@ namespace disvm · 506 unmodified lines
638 class vm_frame_t final650 class vm_frame_t final
639 {651 {
640 public:652 public:
641 vm_frame_t(std::shared_ptr<const type_descriptor_t> &frame_type);653 vm_frame_t(std::shared_ptr<const type_descriptor_t> frame_type);
642 ~vm_frame_t();654 ~vm_frame_t();
643 655
644 std::shared_ptr<const type_descriptor_t> frame_type;656 std::shared_ptr<const type_descriptor_t> frame_type;
src/include/vm_memory.h+31−17
@@ -49,23 +49,37 @@ namespace disvm · 48 unmodified lines
49 // Decrement the ref count and if 0 free the allocation49 // Decrement the ref count and if 0 free the allocation
50 void dec_ref_count_and_free(vm_alloc_t *alloc);50 void dec_ref_count_and_free(vm_alloc_t *alloc);
51 51
52 // Callback for a pointer field supplying the pointer52 // Function to enumerate pointer fields in an object. The function is defined
53 using pointer_field_callback_t = void(*)(pointer_t);53 // as a template to permit raw function pointers or lambdas. The signature
54 54 // of the callback must be 'void(pointer_t *)' and is supplied a pointer to the
55 // The callback will be called on all non-null pointer fields.55 // non-null pointer field. The offset of the field is relative to the supplied
56 void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback);56 // 'data' pointer.
57 57 template<typename CB>
58 // Callback for a pointer field supplying the pointer and a calling context58 void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, CB callback)
59 using pointer_field_callback_ext_t = void(*)(pointer_t, void *cxt);59 {
60 60 assert(data != nullptr && callback != nullptr);
61 // The callback will be called on all non-null pointer fields.61
62 void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_ext_t callback, void *cxt);62 auto memory = reinterpret_cast<word_t *>(data);
63 63 for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8)
64 // Callback for a pointer field supplying the pointer and byte offset64 {
65 using pointer_field_offset_callback_t = std::function<void(pointer_t, std::size_t)>;65 const auto words8 = type_desc.pointer_map[i];
66 66 assert(sizeof(words8) == 1);
67 // The callback will be called on all non-null pointer fields.67 if (words8 == 0)
68 void enum_pointer_fields_with_offset(const type_descriptor_t &type_desc, void *data, pointer_field_offset_callback_t callback);68 continue;
69
70 const auto flags = std::bitset<sizeof(words8) * 8>{ words8 };
71
72 // Enumerating the flags in reverse order so memory access is sequential.
73 if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory));
74 if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 1);
75 if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 2);
76 if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 3);
77 if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 4);
78 if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 5);
79 if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 6);
80 if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t *>(memory) + 7);
81 }
82 }
69 83
70 // Check if a specific pointer-sized offset in a type represents a pointer84 // Check if a specific pointer-sized offset in a type represents a pointer
71 bool is_offset_pointer(const type_descriptor_t &type_desc, std::size_t offset);85 bool is_offset_pointer(const type_descriptor_t &type_desc, std::size_t offset);