History

Created multiple pointer field iterators based on application Fix bug in vm_string class related to appending null at the end of the current string - This was recently introduced because I didn't test the case :( Scheduler had an invalid usage of std::mutex that was found using the debug version of CRT Fix heinous perf issue in GC where it was taking longer than code execution - Switch from std::queue to std::stack -> perf gain of ~20%

arr committed 9 years ago

Commit 30c4c581 parent 6f29a816 files · +102 −39Browse files

Showing the changes to src/vm/vm_memory.cpp (1 of 6 files). Show all

Unified · Split

src/vm/vm_memory.cpp+33−4
@@ -81,13 +81,17 @@ void disvm::runtime::destroy_memory(const type_descriptor_t &type_desc, void *da · 80 unmodified lines
8181
8282 void disvm::runtime::inc_ref_count_in_memory(const type_descriptor_t &type_desc, void *data)
8383 {
84− assert(data != nullptr);
84+ if (type_desc.size_in_bytes == 0)
85+ return;
86+
8587 enum_pointer_fields(type_desc, data, add_ref_pointer_field);
8688 }
8789
8890 void disvm::runtime::dec_ref_count_in_memory(const type_descriptor_t &type_desc, void *data)
8991 {
90− assert(data != nullptr);
92+ if (type_desc.size_in_bytes == 0)
93+ return;
94+
9195 enum_pointer_fields(type_desc, data, dec_ref_and_free_pointer_field);
9296 }
9397
@@ -104,8 +108,6 @@ void disvm::runtime::dec_ref_count_and_free(vm_alloc_t *alloc) · 10 unmodified lines
104108 void disvm::runtime::enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback)
105109 {
106110 assert(data != nullptr && callback != nullptr);
107− if (type_desc.size_in_bytes == 0)
108− return;
109111
110112 auto offset_accum = std::size_t{ 0 };
111113 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
130132 }
131133 }
132134
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+
133162 void disvm::runtime::enum_pointer_fields_with_offset(const type_descriptor_t &type_desc, void *data, pointer_field_offset_callback_t callback)
134163 {
135164 assert(data != nullptr && callback != nullptr);