History

DisVM will now only use 0 initialized memory. - The alloc_memory function will only return 0 initialize memory - calloc_memory was removed

Floating point division is now relying on underlying FPU and IEEE for behavior with respect to divide by 0

arr committed 9 years ago

Commit b92328e1 parent bd1f49311 files · +48 −112Browse files

Unified · Split

11 files
  1. src/exec/main.cpp +1 −1
  2. src/include/debug.h +1 −1
  3. src/include/runtime.h +0 −8
  4. src/include/vm_memory.h +3 −10
  5. src/vm/array.cpp +0 −13
  6. src/vm/execution_table.cpp +23 −9
  7. src/vm/module_reader.cpp +1 −4
  8. src/vm/stack.cpp +1 −1
  9. src/vm/string.cpp +7 −7
  10. src/vm/thread.cpp +4 −3
  11. src/vm/vm_memory.cpp +7 −55
src/exec/main.cpp+1−1
@@ -91,7 +91,7 @@ namespace · 90 unmodified lines
91 91
92 // Initialize the module base register92 // Initialize the module base register
93 const auto mp_type = type_descriptor_t::create(8, { 0xc0 });93 const auto mp_type = type_descriptor_t::create(8, { 0xc0 });
94 e.original_mp.reset(vm_alloc_t::allocate(mp_type, vm_alloc_t::zero_memory));94 e.original_mp.reset(vm_alloc_t::allocate(mp_type));
95 auto mp_base = e.original_mp->get_allocation<pointer_t>();95 auto mp_base = e.original_mp->get_allocation<pointer_t>();
96 96
97 // Take a reference on the command module path and store it on the entry frame97 // Take a reference on the command module path and store it on the entry frame
src/include/debug.h+1−1
@@ -91,7 +91,7 @@ namespace disvm · 90 unmodified lines
91 {91 {
92#ifndef NDEBUG92#ifndef NDEBUG
93 assert(t != nullptr);93 assert(t != nullptr);
94 *t = reinterpret_cast<T *>(0xbada110c);94 assign_debug_memory(t, sizeof(t));
95#endif95#endif
96 }96 }
97 }97 }
src/include/runtime.h+0−8
@@ -89,21 +89,14 @@ namespace disvm · 88 unmodified lines
89 static std::shared_ptr<const type_descriptor_t> type();89 static std::shared_ptr<const type_descriptor_t> type();
90 };90 };
91 91
92 // Type used to indicate allocated memory should be zeroed out.
93 struct zero_memory_t
94 { };
95
96 // VM memory allocation92 // VM memory allocation
97 class vm_alloc_t93 class vm_alloc_t
98 {94 {
99 public: // static95 public: // static
100 static const zero_memory_t zero_memory;
101
102 static void *operator new(std::size_t sz);96 static void *operator new(std::size_t sz);
103 static void operator delete(void *ptr);97 static void operator delete(void *ptr);
104 98
105 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);
106 static vm_alloc_t *allocate(std::shared_ptr<const type_descriptor_t> td, const zero_memory_t &);
107 static vm_alloc_t *copy(const vm_alloc_t &other);100 static vm_alloc_t *copy(const vm_alloc_t &other);
108 static vm_alloc_t *from_allocation(pointer_t allocation);101 static vm_alloc_t *from_allocation(pointer_t allocation);
109 102
@@ -205,7 +198,6 @@ namespace disvm · 95 unmodified lines
205 198
206 public:199 public:
207 vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t length);200 vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t length);
208 vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t length, const zero_memory_t&);
209 vm_array_t(vm_array_t *original, word_t begin_index, word_t length);201 vm_array_t(vm_array_t *original, word_t begin_index, word_t length);
210 vm_array_t(const vm_string_t *s);202 vm_array_t(const vm_string_t *s);
211 ~vm_array_t();203 ~vm_array_t();
src/include/vm_memory.h+3−10
@@ -40,7 +40,9 @@ namespace disvm · 39 unmodified lines
40 // While this lock is taken all further allocations will block.40 // While this lock is taken all further allocations will block.
41 global_alloc_lock_t get_global_alloc_lock();41 global_alloc_lock_t get_global_alloc_lock();
42 42
43 // Allocate memory from the VM heap43 // Allocate memory from the VM heap that is initialize to 0.
44 // [SPEC] All memory in this implementation of the Dis VM spec
45 // will be 0 initialized.
44 void *alloc_memory(std::size_t amount_in_bytes);46 void *alloc_memory(std::size_t amount_in_bytes);
45 47
46 template<typename T>48 template<typename T>
@@ -49,15 +51,6 @@ namespace disvm · 2 unmodified lines
49 return reinterpret_cast<T *>(alloc_memory(amount_in_bytes));51 return reinterpret_cast<T *>(alloc_memory(amount_in_bytes));
50 }52 }
51 53
52 // Allocate memory from the VM heap and initialize to 0.
53 void *calloc_memory(std::size_t amount_in_bytes);
54
55 template<typename T>
56 T *calloc_memory(std::size_t amount_in_bytes = sizeof(T))
57 {
58 return reinterpret_cast<T *>(calloc_memory(amount_in_bytes));
59 }
60
61 // Free memory on the VM heap54 // Free memory on the VM heap
62 void free_memory(void *memory);55 void free_memory(void *memory);
63 56
src/vm/array.cpp+0−13
@@ -43,19 +43,6 @@ vm_array_t::vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t lengt · 42 unmodified lines
43 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: init: elements: %d", array_len);43 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: init: elements: %d", array_len);
44}44}
45 45
46vm_array_t::vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t length, const zero_memory_t&)
47 : vm_alloc_t(vm_array_t::type_desc())
48 , _arr{ nullptr }
49 , _element_type{ td }
50 , _length{ length }
51 , _original{ nullptr }
52{
53 assert(_element_type != nullptr);
54 assert(_length >= 0);
55 _arr = calloc_memory<byte_t>(_length * _element_type->size_in_bytes);
56 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "initz: vm array: %d", _length);
57}
58
59vm_array_t::vm_array_t(vm_array_t *original, word_t begin_index, word_t length)46vm_array_t::vm_array_t(vm_array_t *original, word_t begin_index, word_t length)
60 : vm_alloc_t(vm_array_t::type_desc())47 : vm_alloc_t(vm_array_t::type_desc())
61 , _arr{ nullptr }48 , _arr{ nullptr }
src/vm/execution_table.cpp+23−9
@@ -294,6 +294,16 @@ namespace · 293 unmodified lines
294 vt_ref<PrimitiveType>(r.dest) = vt_ref<PrimitiveType>(r.mid) / denom;294 vt_ref<PrimitiveType>(r.dest) = vt_ref<PrimitiveType>(r.mid) / denom;
295 }295 }
296 296
297 // [SPEC] The C++ defines division by 0 as undefined, however the IEEE standard does
298 // define the behavior. Therefore the behavior is platform dependent and controlled
299 // by the built-in Math module.
300 template<>
301 void _div<real_t>(vm_registers_t &r)
302 {
303 const auto denom = vt_ref<real_t>(r.src);
304 vt_ref<real_t>(r.dest) = vt_ref<real_t>(r.mid) / denom;
305 }
306
297 EXEC_DECL(divb) { _div<byte_t>(r); }307 EXEC_DECL(divb) { _div<byte_t>(r); }
298 EXEC_DECL(divw) { _div<word_t>(r); }308 EXEC_DECL(divw) { _div<word_t>(r); }
299 EXEC_DECL(divf) { _div<real_t>(r); }309 EXEC_DECL(divf) { _div<real_t>(r); }
@@ -1318,7 +1328,7 @@ namespace · 1018 unmodified lines
1318 1328
1319 namespace1329 namespace
1320 {1330 {
1321 void new_instance(vm_registers_t &r, const vm_t &vm, const bool zero_memory)1331 void new_instance(vm_registers_t &r, const vm_t &vm)
1322 {1332 {
1323 const auto type_id = vt_ref<word_t>(r.src);1333 const auto type_id = vt_ref<word_t>(r.src);
1324 const auto &types = r.module_ref->type_section;1334 const auto &types = r.module_ref->type_section;
@@ -1327,7 +1337,7 @@ namespace · 2 unmodified lines
1327 dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest));1337 dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest));
1328 1338
1329 auto type_desc = types[type_id];1339 auto type_desc = types[type_id];
1330 auto new_alloc = !zero_memory ? vm_alloc_t::allocate(type_desc) : vm_alloc_t::allocate(type_desc, vm_alloc_t::zero_memory);1340 auto new_alloc = vm_alloc_t::allocate(type_desc);
1331 1341
1332 if (type_desc->map_in_bytes > 0)1342 if (type_desc->map_in_bytes > 0)
1333 vm.get_garbage_collector().track_allocation(new_alloc);1343 vm.get_garbage_collector().track_allocation(new_alloc);
@@ -1338,12 +1348,14 @@ namespace · 4 unmodified lines
1338 1348
1339 EXEC_DECL(new_)1349 EXEC_DECL(new_)
1340 {1350 {
1341 new_instance(r, vm, false /* zero memory */);1351 new_instance(r, vm);
1342 }1352 }
1343 1353
1344 EXEC_DECL(newz)1354 EXEC_DECL(newz)
1345 {1355 {
1346 new_instance(r, vm, true /* zero memory */);1356 // See allocation implementation for guarantee about
1357 // always using zeroed memory.
1358 new_instance(r, vm);
1347 }1359 }
1348 1360
1349 EXEC_DECL(mnewz)1361 EXEC_DECL(mnewz)
@@ -1359,7 +1371,7 @@ namespace · 9 unmodified lines
1359 dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest));1371 dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest));
1360 1372
1361 auto type_desc = types[type_id];1373 auto type_desc = types[type_id];
1362 auto new_alloc = vm_alloc_t::allocate(type_desc, vm_alloc_t::zero_memory);1374 auto new_alloc = vm_alloc_t::allocate(type_desc);
1363 1375
1364 if (type_desc->map_in_bytes > 0)1376 if (type_desc->map_in_bytes > 0)
1365 vm.get_garbage_collector().track_allocation(new_alloc);1377 vm.get_garbage_collector().track_allocation(new_alloc);
@@ -1369,7 +1381,7 @@ namespace · 3 unmodified lines
1369 1381
1370 namespace1382 namespace
1371 {1383 {
1372 void new_array(vm_registers_t &r, const vm_t &vm, const bool zero_memory)1384 void new_array(vm_registers_t &r, const vm_t &vm)
1373 {1385 {
1374 assert(r.module_ref != nullptr);1386 assert(r.module_ref != nullptr);
1375 const auto &types = r.module_ref->type_section;1387 const auto &types = r.module_ref->type_section;
@@ -1381,7 +1393,7 @@ namespace · 5 unmodified lines
1381 dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest));1393 dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest));
1382 1394
1383 const auto array_size = vt_ref<word_t>(r.src);1395 const auto array_size = vt_ref<word_t>(r.src);
1384 auto new_array = !zero_memory ? new vm_array_t(type_desc, array_size) : new vm_array_t(type_desc, array_size, vm_alloc_t::zero_memory);1396 auto new_array = new vm_array_t(type_desc, array_size);
1385 1397
1386 if (type_desc->map_in_bytes > 0)1398 if (type_desc->map_in_bytes > 0)
1387 vm.get_garbage_collector().track_allocation(new_array);1399 vm.get_garbage_collector().track_allocation(new_array);
@@ -1392,12 +1404,14 @@ namespace · 4 unmodified lines
1392 1404
1393 EXEC_DECL(newa)1405 EXEC_DECL(newa)
1394 {1406 {
1395 new_array(r, vm, false /* zero memory */);1407 new_array(r, vm);
1396 }1408 }
1397 1409
1398 EXEC_DECL(newaz)1410 EXEC_DECL(newaz)
1399 {1411 {
1400 new_array(r, vm, true /* zero memory */);1412 // See allocation implementation for guarantee about
1413 // always using zeroed memory.
1414 new_array(r, vm);
1401 }1415 }
1402 1416
1403 EXEC_DECL(tcmp)1417 EXEC_DECL(tcmp)
src/vm/module_reader.cpp+1−4
@@ -362,10 +362,7 @@ namespace · 361 unmodified lines
362 {362 {
363 auto vm_module_type = modobj.type_section[module_constants::vm_module_type_desc_number];363 auto vm_module_type = modobj.type_section[module_constants::vm_module_type_desc_number];
364 if (vm_module_type->size_in_bytes != modobj.header.data_size) throw module_reader_exception{ "Invalid type desc for MP" };364 if (vm_module_type->size_in_bytes != modobj.header.data_size) throw module_reader_exception{ "Invalid type desc for MP" };
365 365 modobj.original_mp.reset(vm_alloc_t::allocate(vm_module_type));
366 // [SPEC] The Dis VM spec does not guarantee the MP segment (i.e. data segment) of the loaded
367 // module will be initialized to zero, but it is the C/C++ approach so defer to that.
368 modobj.original_mp.reset(vm_alloc_t::allocate(vm_module_type, vm_alloc_t::zero_memory));
369 }366 }
370 367
371 auto array_stack = std::array<byte_t *, module_constants::array_address_stack_size>{};368 auto array_stack = std::array<byte_t *, module_constants::array_address_stack_size>{};
src/vm/stack.cpp+1−1
@@ -66,7 +66,7 @@ namespace · 65 unmodified lines
66 void *new_page()66 void *new_page()
67 {67 {
68 auto current_stack_page = top_page;68 auto current_stack_page = top_page;
69 top_page = calloc_memory<vm_stack_page>(sizeof(vm_stack_page) + stack_page_size);69 top_page = alloc_memory<vm_stack_page>(sizeof(vm_stack_page) + stack_page_size);
70 70
71 // Initialize the stack allocation.71 // Initialize the stack allocation.
72 top_page->prev_page = current_stack_page;72 top_page->prev_page = current_stack_page;
src/vm/string.cpp+7−7
@@ -217,7 +217,7 @@ vm_string_t::vm_string_t(std::size_t encoded_str_len, const uint8_t *encoded_str · 216 unmodified lines
217 {217 {
218 // If we are going to allocate, make sure it is larger than needed.218 // If we are going to allocate, make sure it is larger than needed.
219 _length_max = compute_max_length(_length);219 _length_max = compute_max_length(_length);
220 _mem.alloc = calloc_memory<uint8_t>(_length_max * _character_size);220 _mem.alloc = alloc_memory<uint8_t>(_length_max * _character_size);
221 _is_alloc = true;221 _is_alloc = true;
222 222
223 dest = _mem.alloc;223 dest = _mem.alloc;
@@ -248,7 +248,7 @@ vm_string_t::vm_string_t(const vm_string_t &s1, const vm_string_t &s2) · 24 unmodified lines
248 , _length_max{ compute_max_length(s1._length + s2._length) }248 , _length_max{ compute_max_length(s1._length + s2._length) }
249 , _mem{}249 , _mem{}
250{250{
251 _mem.alloc = calloc_memory<uint8_t>(_length_max * _character_size);251 _mem.alloc = alloc_memory<uint8_t>(_length_max * _character_size);
252 252
253 const auto s1_data = (s1._is_alloc) ? s1._mem.alloc : s1._mem.local;253 const auto s1_data = (s1._is_alloc) ? s1._mem.alloc : s1._mem.local;
254 const auto s2_data = (s2._is_alloc) ? s2._mem.alloc : s2._mem.local;254 const auto s2_data = (s2._is_alloc) ? s2._mem.alloc : s2._mem.local;
@@ -290,7 +290,7 @@ vm_string_t::vm_string_t(const vm_string_t &other, word_t begin_index, word_t en · 35 unmodified lines
290 if (_is_alloc)290 if (_is_alloc)
291 {291 {
292 src = other._mem.alloc;292 src = other._mem.alloc;
293 _mem.alloc = calloc_memory<uint8_t>(_length_max);293 _mem.alloc = alloc_memory<uint8_t>(_length_max);
294 dest = _mem.alloc;294 dest = _mem.alloc;
295 }295 }
296 296
@@ -358,9 +358,9 @@ vm_string_t &vm_string_t::append(const vm_string_t &other) · 61 unmodified lines
358 358
359 // Check if this string and the supplied string have the same character size.359 // Check if this string and the supplied string have the same character size.
360 if (new_is_rune)360 if (new_is_rune)
361 new_source = calloc_memory<uint8_t>(new_length_max * sizeof(rune_t));361 new_source = alloc_memory<uint8_t>(new_length_max * sizeof(rune_t));
362 else362 else
363 new_source = calloc_memory<uint8_t>(new_length_max);363 new_source = alloc_memory<uint8_t>(new_length_max);
364 364
365 // Combine the two string sources365 // Combine the two string sources
366 combine(366 combine(
@@ -449,7 +449,7 @@ void vm_string_t::set_rune(word_t index, rune_t value) · 82 unmodified lines
449 assert(_character_size == sizeof(rune_t));449 assert(_character_size == sizeof(rune_t));
450 450
451 _length_max = (_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(_length);451 _length_max = (_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(_length);
452 auto new_alloc = calloc_memory<rune_t>(_length_max * _character_size);452 auto new_alloc = alloc_memory<rune_t>(_length_max * _character_size);
453 453
454 // Copy source into the new alloc.454 // Copy source into the new alloc.
455 copy_characters_to(new_alloc, 0, source, _length);455 copy_characters_to(new_alloc, 0, source, _length);
@@ -467,7 +467,7 @@ void vm_string_t::set_rune(word_t index, rune_t value) · 11 unmodified lines
467 else if (static_cast<word_t>(_length_max) <= index) // Check if string can accomodate the new character.467 else if (static_cast<word_t>(_length_max) <= index) // Check if string can accomodate the new character.
468 {468 {
469 _length_max = (_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(_length);469 _length_max = (_length == 0) ? static_cast<word_t>(compute_max_length(_mem.local)) : compute_max_length(_length);
470 auto new_alloc = calloc_memory<uint8_t>(_length_max * _character_size);470 auto new_alloc = alloc_memory<uint8_t>(_length_max * _character_size);
471 std::memcpy(new_alloc, source, _length * _character_size);471 std::memcpy(new_alloc, source, _length * _character_size);
472 472
473 // Free memory, if allocated473 // Free memory, if allocated
src/vm/thread.cpp+4−3
@@ -255,7 +255,7 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 254 unmodified lines
255 }255 }
256 catch (const unhandled_user_exception &uue)256 catch (const unhandled_user_exception &uue)
257 {257 {
258 _error_message = calloc_memory<char>(max_error_message);258 _error_message = alloc_memory<char>(max_error_message);
259 const int ec = std::snprintf(_error_message, max_error_message, "%s in %s @%d\n %s", uue.what(), uue.module_name, uue.program_counter, uue.exception_id);259 const int ec = std::snprintf(_error_message, max_error_message, "%s in %s @%d\n %s", uue.what(), uue.module_name, uue.program_counter, uue.exception_id);
260 assert(ec > 0 && ec < max_error_message);260 assert(ec > 0 && ec < max_error_message);
261 (void)ec;261 (void)ec;
@@ -263,7 +263,7 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 1 unmodified line
263 }263 }
264 catch (const index_out_of_range_memory &ioor)264 catch (const index_out_of_range_memory &ioor)
265 {265 {
266 _error_message = calloc_memory<char>(max_error_message);266 _error_message = alloc_memory<char>(max_error_message);
267 const int ec = std::snprintf(_error_message, max_error_message, "%s - %d [%d,%d]", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max);267 const int ec = std::snprintf(_error_message, max_error_message, "%s - %d [%d,%d]", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max);
268 assert(ec > 0 && ec < max_error_message);268 assert(ec > 0 && ec < max_error_message);
269 (void)ec;269 (void)ec;
@@ -271,7 +271,8 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 1 unmodified line
271 }271 }
272 catch (const vm_user_exception &ue)272 catch (const vm_user_exception &ue)
273 {273 {
274 _error_message = calloc_memory<char>(max_error_message);274 // [TODO] Include the module and IP to aid in debugging.
275 _error_message = alloc_memory<char>(max_error_message);
275 const int ec = std::snprintf(_error_message, max_error_message, "%s", ue.what());276 const int ec = std::snprintf(_error_message, max_error_message, "%s", ue.what());
276 assert(ec > 0 && ec < max_error_message);277 assert(ec > 0 && ec < max_error_message);
277 (void)ec;278 (void)ec;
src/vm/vm_memory.cpp+7−55
@@ -106,7 +106,7 @@ void *disvm::runtime::alloc_memory(std::size_t amount_in_bytes) · 105 unmodified lines
106{106{
107 safe_alloc s;107 safe_alloc s;
108 108
109 auto memory = std::malloc(amount_in_bytes);109 auto memory = std::calloc(amount_in_bytes, sizeof(byte_t));
110 if (memory == nullptr)110 if (memory == nullptr)
111 throw vm_system_exception{ "Out of memory" };111 throw vm_system_exception{ "Out of memory" };
112 112
@@ -116,20 +116,6 @@ void *disvm::runtime::alloc_memory(std::size_t amount_in_bytes) · 3 unmodified lines
116 return memory;116 return memory;
117}117}
118 118
119void *disvm::runtime::calloc_memory(std::size_t amount_in_bytes)
120{
121 safe_alloc s;
122
123 auto memory = std::calloc(amount_in_bytes, sizeof(uint8_t));
124 if (memory == nullptr)
125 throw vm_system_exception{ "Out of memory" };
126
127 if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
128 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "alloc: zeroed: %#" PRIxPTR " %d", memory, amount_in_bytes);
129
130 return memory;
131}
132
133void disvm::runtime::free_memory(void *memory)119void disvm::runtime::free_memory(void *memory)
134{120{
135 if (memory == nullptr)121 if (memory == nullptr)
@@ -147,27 +133,12 @@ void disvm::runtime::init_memory(const type_descriptor_t &type_desc, void *data) · 11 unmodified lines
147 if (type_desc.size_in_bytes == 0)133 if (type_desc.size_in_bytes == 0)
148 return;134 return;
149 135
150 debug::assign_debug_memory(data, type_desc.size_in_bytes);136 // [SPEC] The Dis VM spec does not guarantee non-pointer offsets
151 137 // to be initialized to zero, but it was found to be an assumption
152 auto memory = reinterpret_cast<word_t *>(data);138 // when getting the limbo compiler run on this VM. Therefore this
153 for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8)139 // implemetation will make the strong guarantee that memory will
154 {140 // always be 0 initialized.
155 const auto words8 = type_desc.pointer_map[i];141 std::memset(data, 0, type_desc.size_in_bytes);
156 if (words8 != 0)
157 {
158 const auto flags = std::bitset<sizeof(words8) * 8>{ words8 };
159
160 // Enumerating the flags in reverse order so memory access is linear.
161 if (flags[7]) memory[0] = runtime_constants::nil;
162 if (flags[6]) memory[1] = runtime_constants::nil;
163 if (flags[5]) memory[2] = runtime_constants::nil;
164 if (flags[4]) memory[3] = runtime_constants::nil;
165 if (flags[3]) memory[4] = runtime_constants::nil;
166 if (flags[2]) memory[5] = runtime_constants::nil;
167 if (flags[1]) memory[6] = runtime_constants::nil;
168 if (flags[0]) memory[7] = runtime_constants::nil;
169 }
170 }
171}142}
172 143
173namespace144namespace
@@ -210,8 +181,6 @@ void disvm::runtime::dec_ref_count_and_free(vm_alloc_t *alloc) · 36 unmodified lines
210 delete alloc;181 delete alloc;
211}182}
212 183
213const zero_memory_t vm_alloc_t::zero_memory = {};
214
215void *vm_alloc_t::operator new(std::size_t sz)184void *vm_alloc_t::operator new(std::size_t sz)
216{185{
217 return alloc_memory(sz);186 return alloc_memory(sz);
@@ -231,27 +200,10 @@ vm_alloc_t *vm_alloc_t::allocate(std::shared_ptr<const type_descriptor_t> td) · 13 unmodified lines
231 auto mem = alloc_memory(sizeof(vm_alloc_t) + td->size_in_bytes);200 auto mem = alloc_memory(sizeof(vm_alloc_t) + td->size_in_bytes);
232 auto alloc = ::new(mem)vm_alloc_t{ td };201 auto alloc = ::new(mem)vm_alloc_t{ td };
233 202
234 // Initialize pointer types
235 init_memory(*td, alloc->get_allocation());
236
237 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm alloc: %d", td->size_in_bytes);203 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm alloc: %d", td->size_in_bytes);
238 return alloc;204 return alloc;
239}205}
240 206
241vm_alloc_t *vm_alloc_t::allocate(std::shared_ptr<const type_descriptor_t> td, const zero_memory_t &)
242{
243 assert(td != nullptr);
244 if (td->size_in_bytes <= 0)
245 throw vm_system_exception{ "Invalid dynamic memory allocation size" };
246
247 // No need to initialize memory since it is already zeroed out.
248 auto mem = calloc_memory(sizeof(vm_alloc_t) + td->size_in_bytes);
249 auto alloc = ::new(mem)vm_alloc_t{ td };
250
251 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "initz: vm alloc: %d", td->size_in_bytes);
252 return alloc;
253}
254
255vm_alloc_t *vm_alloc_t::copy(const vm_alloc_t &other)207vm_alloc_t *vm_alloc_t::copy(const vm_alloc_t &other)
256{208{
257 auto alloc_copy = vm_alloc_t::allocate(other.alloc_type);209 auto alloc_copy = vm_alloc_t::allocate(other.alloc_type);