Floating point division is now relying on underlying FPU and IEEE for behavior with respect to divide by 0
Unified · Split
| @@ -91,7 +91,7 @@ namespace · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | // Initialize the module base register |
| 93 | 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 | 95 | auto mp_base = e.original_mp->get_allocation<pointer_t>(); |
| 96 | 96 | |
| 97 | 97 | // Take a reference on the command module path and store it on the entry frame |
| @@ -91,7 +91,7 @@ namespace disvm · 90 unmodified lines | ||
| 91 | 91 | { |
| 92 | 92 | #ifndef NDEBUG |
| 93 | 93 | assert(t != nullptr); |
| 94 | − *t = reinterpret_cast<T *>(0xbada110c); | |
| 94 | + assign_debug_memory(t, sizeof(t)); | |
| 95 | 95 | #endif |
| 96 | 96 | } |
| 97 | 97 | } |
| @@ -89,21 +89,14 @@ namespace disvm · 88 unmodified lines | ||
| 89 | 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 | 92 | // VM memory allocation |
| 97 | 93 | class vm_alloc_t |
| 98 | 94 | { |
| 99 | 95 | public: // static |
| 100 | − static const zero_memory_t zero_memory; | |
| 101 | − | |
| 102 | 96 | static void *operator new(std::size_t sz); |
| 103 | 97 | static void operator delete(void *ptr); |
| 104 | 98 | |
| 105 | 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 | 100 | static vm_alloc_t *copy(const vm_alloc_t &other); |
| 108 | 101 | static vm_alloc_t *from_allocation(pointer_t allocation); |
| 109 | 102 | |
| @@ -205,7 +198,6 @@ namespace disvm · 95 unmodified lines | ||
| 205 | 198 | |
| 206 | 199 | public: |
| 207 | 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 | 201 | vm_array_t(vm_array_t *original, word_t begin_index, word_t length); |
| 210 | 202 | vm_array_t(const vm_string_t *s); |
| 211 | 203 | ~vm_array_t(); |
| @@ -40,7 +40,9 @@ namespace disvm · 39 unmodified lines | ||
| 40 | 40 | // While this lock is taken all further allocations will block. |
| 41 | 41 | global_alloc_lock_t get_global_alloc_lock(); |
| 42 | 42 | |
| 43 | − // Allocate memory from the VM heap | |
| 43 | + // 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 | 46 | void *alloc_memory(std::size_t amount_in_bytes); |
| 45 | 47 | |
| 46 | 48 | template<typename T> |
| @@ -49,15 +51,6 @@ namespace disvm · 2 unmodified lines | ||
| 49 | 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 | 54 | // Free memory on the VM heap |
| 62 | 55 | void free_memory(void *memory); |
| 63 | 56 | |
| @@ -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 | 43 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: init: elements: %d", array_len); |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | −vm_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 | − | |
| 59 | 46 | vm_array_t::vm_array_t(vm_array_t *original, word_t begin_index, word_t length) |
| 60 | 47 | : vm_alloc_t(vm_array_t::type_desc()) |
| 61 | 48 | , _arr{ nullptr } |
| @@ -294,6 +294,16 @@ namespace · 293 unmodified lines | ||
| 294 | 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 | 307 | EXEC_DECL(divb) { _div<byte_t>(r); } |
| 298 | 308 | EXEC_DECL(divw) { _div<word_t>(r); } |
| 299 | 309 | EXEC_DECL(divf) { _div<real_t>(r); } |
| @@ -1318,7 +1328,7 @@ namespace · 1018 unmodified lines | ||
| 1318 | 1328 | |
| 1319 | 1329 | 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 | 1333 | const auto type_id = vt_ref<word_t>(r.src); |
| 1324 | 1334 | const auto &types = r.module_ref->type_section; |
| @@ -1327,7 +1337,7 @@ namespace · 2 unmodified lines | ||
| 1327 | 1337 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); |
| 1328 | 1338 | |
| 1329 | 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 | 1342 | if (type_desc->map_in_bytes > 0) |
| 1333 | 1343 | vm.get_garbage_collector().track_allocation(new_alloc); |
| @@ -1338,12 +1348,14 @@ namespace · 4 unmodified lines | ||
| 1338 | 1348 | |
| 1339 | 1349 | EXEC_DECL(new_) |
| 1340 | 1350 | { |
| 1341 | − new_instance(r, vm, false /* zero memory */); | |
| 1351 | + new_instance(r, vm); | |
| 1342 | 1352 | } |
| 1343 | 1353 | |
| 1344 | 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 | 1361 | EXEC_DECL(mnewz) |
| @@ -1359,7 +1371,7 @@ namespace · 9 unmodified lines | ||
| 1359 | 1371 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); |
| 1360 | 1372 | |
| 1361 | 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 | 1376 | if (type_desc->map_in_bytes > 0) |
| 1365 | 1377 | vm.get_garbage_collector().track_allocation(new_alloc); |
| @@ -1369,7 +1381,7 @@ namespace · 3 unmodified lines | ||
| 1369 | 1381 | |
| 1370 | 1382 | 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 | 1386 | assert(r.module_ref != nullptr); |
| 1375 | 1387 | const auto &types = r.module_ref->type_section; |
| @@ -1381,7 +1393,7 @@ namespace · 5 unmodified lines | ||
| 1381 | 1393 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); |
| 1382 | 1394 | |
| 1383 | 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 | 1398 | if (type_desc->map_in_bytes > 0) |
| 1387 | 1399 | vm.get_garbage_collector().track_allocation(new_array); |
| @@ -1392,12 +1404,14 @@ namespace · 4 unmodified lines | ||
| 1392 | 1404 | |
| 1393 | 1405 | EXEC_DECL(newa) |
| 1394 | 1406 | { |
| 1395 | − new_array(r, vm, false /* zero memory */); | |
| 1407 | + new_array(r, vm); | |
| 1396 | 1408 | } |
| 1397 | 1409 | |
| 1398 | 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 | 1417 | EXEC_DECL(tcmp) |
| @@ -362,10 +362,7 @@ namespace · 361 unmodified lines | ||
| 362 | 362 | { |
| 363 | 363 | auto vm_module_type = modobj.type_section[module_constants::vm_module_type_desc_number]; |
| 364 | 364 | if (vm_module_type->size_in_bytes != modobj.header.data_size) throw module_reader_exception{ "Invalid type desc for MP" }; |
| 365 | − | |
| 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)); | |
| 365 | + modobj.original_mp.reset(vm_alloc_t::allocate(vm_module_type)); | |
| 369 | 366 | } |
| 370 | 367 | |
| 371 | 368 | auto array_stack = std::array<byte_t *, module_constants::array_address_stack_size>{}; |
| @@ -66,7 +66,7 @@ namespace · 65 unmodified lines | ||
| 66 | 66 | void *new_page() |
| 67 | 67 | { |
| 68 | 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 | 71 | // Initialize the stack allocation. |
| 72 | 72 | top_page->prev_page = current_stack_page; |
| @@ -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 | 218 | // If we are going to allocate, make sure it is larger than needed. |
| 219 | 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 | 221 | _is_alloc = true; |
| 222 | 222 | |
| 223 | 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 | 248 | , _length_max{ compute_max_length(s1._length + s2._length) } |
| 249 | 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 | 253 | const auto s1_data = (s1._is_alloc) ? s1._mem.alloc : s1._mem.local; |
| 254 | 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 | 290 | if (_is_alloc) |
| 291 | 291 | { |
| 292 | 292 | src = other._mem.alloc; |
| 293 | − _mem.alloc = calloc_memory<uint8_t>(_length_max); | |
| 293 | + _mem.alloc = alloc_memory<uint8_t>(_length_max); | |
| 294 | 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 | 359 | // Check if this string and the supplied string have the same character size. |
| 360 | 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 | 362 | else |
| 363 | − new_source = calloc_memory<uint8_t>(new_length_max); | |
| 363 | + new_source = alloc_memory<uint8_t>(new_length_max); | |
| 364 | 364 | |
| 365 | 365 | // Combine the two string sources |
| 366 | 366 | combine( |
| @@ -449,7 +449,7 @@ void vm_string_t::set_rune(word_t index, rune_t value) · 82 unmodified lines | ||
| 449 | 449 | assert(_character_size == sizeof(rune_t)); |
| 450 | 450 | |
| 451 | 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 | 454 | // Copy source into the new alloc. |
| 455 | 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 | 467 | else if (static_cast<word_t>(_length_max) <= index) // Check if string can accomodate the new character. |
| 468 | 468 | { |
| 469 | 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 | 471 | std::memcpy(new_alloc, source, _length * _character_size); |
| 472 | 472 | |
| 473 | 473 | // Free memory, if allocated |
| @@ -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 | 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 | 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 | 260 | assert(ec > 0 && ec < max_error_message); |
| 261 | 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 | 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 | 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 | 268 | assert(ec > 0 && ec < max_error_message); |
| 269 | 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 | 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 | 276 | const int ec = std::snprintf(_error_message, max_error_message, "%s", ue.what()); |
| 276 | 277 | assert(ec > 0 && ec < max_error_message); |
| 277 | 278 | (void)ec; |
| @@ -106,7 +106,7 @@ void *disvm::runtime::alloc_memory(std::size_t amount_in_bytes) · 105 unmodified lines | ||
| 106 | 106 | { |
| 107 | 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 | 110 | if (memory == nullptr) |
| 111 | 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 | 116 | return memory; |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | −void *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 | − | |
| 133 | 119 | void disvm::runtime::free_memory(void *memory) |
| 134 | 120 | { |
| 135 | 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 | 133 | if (type_desc.size_in_bytes == 0) |
| 148 | 134 | return; |
| 149 | 135 | |
| 150 | − debug::assign_debug_memory(data, type_desc.size_in_bytes); | |
| 151 | − | |
| 152 | − auto memory = reinterpret_cast<word_t *>(data); | |
| 153 | − for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8) | |
| 154 | − { | |
| 155 | − const auto words8 = type_desc.pointer_map[i]; | |
| 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 | − } | |
| 136 | + // [SPEC] The Dis VM spec does not guarantee non-pointer offsets | |
| 137 | + // to be initialized to zero, but it was found to be an assumption | |
| 138 | + // when getting the limbo compiler run on this VM. Therefore this | |
| 139 | + // implemetation will make the strong guarantee that memory will | |
| 140 | + // always be 0 initialized. | |
| 141 | + std::memset(data, 0, type_desc.size_in_bytes); | |
| 171 | 142 | } |
| 172 | 143 | |
| 173 | 144 | namespace |
| @@ -210,8 +181,6 @@ void disvm::runtime::dec_ref_count_and_free(vm_alloc_t *alloc) · 36 unmodified lines | ||
| 210 | 181 | delete alloc; |
| 211 | 182 | } |
| 212 | 183 | |
| 213 | −const zero_memory_t vm_alloc_t::zero_memory = {}; | |
| 214 | − | |
| 215 | 184 | void *vm_alloc_t::operator new(std::size_t sz) |
| 216 | 185 | { |
| 217 | 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 | 200 | auto mem = alloc_memory(sizeof(vm_alloc_t) + td->size_in_bytes); |
| 232 | 201 | auto alloc = ::new(mem)vm_alloc_t{ td }; |
| 233 | 202 | |
| 234 | − // Initialize pointer types | |
| 235 | − init_memory(*td, alloc->get_allocation()); | |
| 236 | − | |
| 237 | 203 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm alloc: %d", td->size_in_bytes); |
| 238 | 204 | return alloc; |
| 239 | 205 | } |
| 240 | 206 | |
| 241 | −vm_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 | − | |
| 255 | 207 | vm_alloc_t *vm_alloc_t::copy(const vm_alloc_t &other) |
| 256 | 208 | { |
| 257 | 209 | auto alloc_copy = vm_alloc_t::allocate(other.alloc_type); |