Showing the changes to src/vm/vm_memory.cpp (1 of 6 files). Show all
Unified · Split
| @@ -81,13 +81,17 @@ void disvm::runtime::destroy_memory(const type_descriptor_t &type_desc, void *da · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | void disvm::runtime::inc_ref_count_in_memory(const type_descriptor_t &type_desc, void *data) |
| 83 | 83 | { |
| 84 | − assert(data != nullptr); | |
| 84 | + if (type_desc.size_in_bytes == 0) | |
| 85 | + return; | |
| 86 | + | |
| 85 | 87 | enum_pointer_fields(type_desc, data, add_ref_pointer_field); |
| 86 | 88 | } |
| 87 | 89 | |
| 88 | 90 | void disvm::runtime::dec_ref_count_in_memory(const type_descriptor_t &type_desc, void *data) |
| 89 | 91 | { |
| 90 | − assert(data != nullptr); | |
| 92 | + if (type_desc.size_in_bytes == 0) | |
| 93 | + return; | |
| 94 | + | |
| 91 | 95 | enum_pointer_fields(type_desc, data, dec_ref_and_free_pointer_field); |
| 92 | 96 | } |
| 93 | 97 | |
| @@ -104,8 +108,6 @@ void disvm::runtime::dec_ref_count_and_free(vm_alloc_t *alloc) · 10 unmodified lines | ||
| 104 | 108 | void disvm::runtime::enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback) |
| 105 | 109 | { |
| 106 | 110 | assert(data != nullptr && callback != nullptr); |
| 107 | − if (type_desc.size_in_bytes == 0) | |
| 108 | − return; | |
| 109 | 111 | |
| 110 | 112 | auto offset_accum = std::size_t{ 0 }; |
| 111 | 113 | auto memory = reinterpret_cast<word_t *>(data); |
| @@ -130,6 +132,33 @@ void disvm::runtime::enum_pointer_fields(const type_descriptor_t &type_desc, voi · 18 unmodified lines | ||
| 130 | 132 | } |
| 131 | 133 | } |
| 132 | 134 | |
| 135 | +void disvm::runtime::enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_ext_t callback, void *cxt) | |
| 136 | +{ | |
| 137 | + assert(data != nullptr && callback != nullptr); | |
| 138 | + | |
| 139 | + auto offset_accum = std::size_t{ 0 }; | |
| 140 | + auto memory = reinterpret_cast<word_t *>(data); | |
| 141 | + for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8, offset_accum += (8 * sizeof(pointer_t))) | |
| 142 | + { | |
| 143 | + const auto words8 = type_desc.pointer_map[i]; | |
| 144 | + assert(sizeof(words8) == 1); | |
| 145 | + if (words8 == 0) | |
| 146 | + continue; | |
| 147 | + | |
| 148 | + const auto flags = std::bitset<sizeof(words8) * 8>{ words8 }; | |
| 149 | + | |
| 150 | + // Enumerating the flags in reverse order so memory access is sequential. | |
| 151 | + if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[0]), cxt); | |
| 152 | + if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[1]), cxt); | |
| 153 | + if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[2]), cxt); | |
| 154 | + if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[3]), cxt); | |
| 155 | + if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[4]), cxt); | |
| 156 | + if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[5]), cxt); | |
| 157 | + if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[6]), cxt); | |
| 158 | + if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[7]), cxt); | |
| 159 | + } | |
| 160 | +} | |
| 161 | + | |
| 133 | 162 | void disvm::runtime::enum_pointer_fields_with_offset(const type_descriptor_t &type_desc, void *data, pointer_field_offset_callback_t callback) |
| 134 | 163 | { |
| 135 | 164 | assert(data != nullptr && callback != nullptr); |