Floating point division is now relying on underlying FPU and IEEE for behavior with respect to divide by 0
Showing the changes to src/vm/vm_memory.cpp (1 of 11 files). Show all
Unified · Split
| @@ -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 | ||
| 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 | void disvm::runtime::free_memory(void *memory) | 119 | void 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 | ||
| 173 | namespace | 144 | namespace |
| @@ -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 | ||
| 213 | const zero_memory_t vm_alloc_t::zero_memory = {}; | ||
| 214 | |||
| 215 | void *vm_alloc_t::operator new(std::size_t sz) | 184 | void *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 | ||
| 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 | vm_alloc_t *vm_alloc_t::copy(const vm_alloc_t &other) | 207 | vm_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); |