History

Alter debugger API to accept vector value not reference.

Remove global memory lock mechanism - Wasn't being used but showed up on profile report :( Move enum_pointer_fields and is_offset_pointer impls into cpp file Create enum_pointer_fields_with_offset function since the VM never needs the offset values and the generated code was about 5% bigger. Now the VM can use the callback without the offset. Removed pointless init_memory() usage since alloc_memory() now is required to return zeroed out memory. Fixed bugs in GC Added support - Ranged absolute disassembly in debugger - New duration log component

arr committed 9 years ago

Commit cc8f2b61 parent 41616d412 files · +167 −250Browse files

Showing the changes to src/include (3 of 12 files). Show all

Unified · Split

3 files
  1. src/include/debug.h +2 −1
  2. src/include/runtime.h +2 −2
  3. src/include/vm_memory.h +9 −72
src/include/debug.h+2−1
@@ -31,9 +31,10 @@ namespace disvm · 30 unmodified lines
31 // Potentially logged from a VM extension.31 // Potentially logged from a VM extension.
32 scheduler,32 scheduler,
33 garbage_collector,33 garbage_collector,
34 duration,
34 35
35 // Tracking purposes36 // Tracking purposes
36 last = garbage_collector37 last = duration
37 };38 };
38 39
39 // Trace component enable state.40 // Trace component enable state.
src/include/runtime.h+2−2
@@ -104,7 +104,7 @@ namespace disvm · 103 unmodified lines
104 static T *from_allocation(pointer_t allocation)104 static T *from_allocation(pointer_t allocation)
105 {105 {
106 auto alloc_inst = vm_alloc_t::from_allocation(allocation);106 auto alloc_inst = vm_alloc_t::from_allocation(allocation);
107 assert(alloc_inst == nullptr || alloc_inst->alloc_type == intrinsic_type_desc::type<T>());107 assert(alloc_inst == nullptr || alloc_inst->alloc_type->is_equal(intrinsic_type_desc::type<T>().get()));
108 return static_cast<T *>(alloc_inst);108 return static_cast<T *>(alloc_inst);
109 }109 }
110 110
@@ -875,7 +875,7 @@ namespace disvm · 764 unmodified lines
875 // Called by the scheduler to inform the collector it should attempt to free resources.875 // Called by the scheduler to inform the collector it should attempt to free resources.
876 // All VM threads are guaranteed to be idle when called.876 // All VM threads are guaranteed to be idle when called.
877 // Returns true if the collection algorithm was run, otherwise false.877 // Returns true if the collection algorithm was run, otherwise false.
878 virtual bool collect(std::vector<std::shared_ptr<const vm_thread_t>> &threads) = 0;878 virtual bool collect(std::vector<std::shared_ptr<const vm_thread_t>> threads) = 0;
879 };879 };
880 880
881 // Create a garbage collector that does nothing.881 // Create a garbage collector that does nothing.
src/include/vm_memory.h+9−72
@@ -20,26 +20,6 @@ namespace disvm · 19 unmodified lines
20{20{
21 namespace runtime21 namespace runtime
22 {22 {
23 class global_alloc_lock_t final
24 {
25 public:
26 global_alloc_lock_t(const global_alloc_lock_t &) = delete;
27 global_alloc_lock_t& operator=(const global_alloc_lock_t &) = delete;
28
29 global_alloc_lock_t(global_alloc_lock_t &&);
30
31 ~global_alloc_lock_t();
32
33 private:
34 bool _owner;
35 global_alloc_lock_t(bool owner);
36 friend global_alloc_lock_t get_global_alloc_lock();
37 };
38
39 // Take the global allocation lock for the VM heap.
40 // While this lock is taken all further allocations will block.
41 global_alloc_lock_t get_global_alloc_lock();
42
43 // Allocate memory from the VM heap that is initialize to 0.23 // Allocate memory from the VM heap that is initialize to 0.
44 // [SPEC] All memory in this implementation of the Dis VM spec24 // [SPEC] All memory in this implementation of the Dis VM spec
45 // will be 0 initialized.25 // will be 0 initialized.
@@ -69,63 +49,20 @@ namespace disvm · 23 unmodified lines
69 // Decrement the ref count and if 0 free the allocation49 // Decrement the ref count and if 0 free the allocation
70 void dec_ref_count_and_free(vm_alloc_t *alloc);50 void dec_ref_count_and_free(vm_alloc_t *alloc);
71 51
52 // Callback for a pointer field supplying the pointer
53 using pointer_field_callback_t = std::function<void(pointer_t)>;
54
55 // The callback will be called on all non-null pointer fields.
56 void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback);
57
72 // Callback for a pointer field supplying the pointer and byte offset58 // Callback for a pointer field supplying the pointer and byte offset
73 using pointer_field_callback_t = std::function<void(pointer_t, std::size_t)>;59 using pointer_field_offset_callback_t = std::function<void(pointer_t, std::size_t)>;
74 60
75 // The callback will be called on all non-null pointer fields.61 // The callback will be called on all non-null pointer fields.
76 inline void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback)62 void enum_pointer_fields_with_offset(const type_descriptor_t &type_desc, void *data, pointer_field_offset_callback_t callback);
77 {
78 assert(data != nullptr && callback != nullptr);
79 if (type_desc.size_in_bytes == 0)
80 return;
81
82 auto offset_accum = std::size_t{ 0 };
83 auto memory = reinterpret_cast<word_t *>(data);
84 for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8, offset_accum += (8 * sizeof(pointer_t)))
85 {
86 const auto words8 = type_desc.pointer_map[i];
87 assert(sizeof(words8) == 1);
88 if (words8 == 0)
89 continue;
90
91 const auto flags = std::bitset<sizeof(words8) * 8>{ words8 };
92
93 // Enumerating the flags in reverse order so memory access is sequential.
94 if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[0]), offset_accum);
95 if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[1]), offset_accum + (1 * sizeof(pointer_t)));
96 if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[2]), offset_accum + (2 * sizeof(pointer_t)));
97 if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[3]), offset_accum + (3 * sizeof(pointer_t)));
98 if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[4]), offset_accum + (4 * sizeof(pointer_t)));
99 if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[5]), offset_accum + (5 * sizeof(pointer_t)));
100 if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[6]), offset_accum + (6 * sizeof(pointer_t)));
101 if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[7]), offset_accum + (7 * sizeof(pointer_t)));
102 }
103 }
104 63
105 // Check if a specific pointer-sized offset in a type represents a pointer64 // Check if a specific pointer-sized offset in a type represents a pointer
106 inline bool is_offset_pointer(const type_descriptor_t &type_desc, std::size_t offset)65 bool is_offset_pointer(const type_descriptor_t &type_desc, std::size_t offset);
107 {
108 if (type_desc.size_in_bytes == 0)
109 return false;
110
111 assert(offset < static_cast<std::size_t>(std::numeric_limits<word_t>::max()));
112 const auto byte_offset = static_cast<word_t>(offset / 8);
113
114 // Highest order bit is the first field
115 const auto bit_offset = 7 - (offset % 8);
116 if (byte_offset < type_desc.map_in_bytes)
117 {
118 const auto words8 = type_desc.pointer_map[byte_offset];
119 assert(sizeof(words8) == 1);
120 if (words8 != 0)
121 {
122 const auto flags = std::bitset<sizeof(words8) * 8>{ words8 };
123 return flags[bit_offset];
124 }
125 }
126
127 return false;
128 }
129 }66 }
130}67}
131 68

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t