History

Bugs found during limbo compiler work - Ref counting mistakes in vm_array copy_from() - document perf opportunity - Multiple bugs in addc instruction - set_rune() on vm_string was creating non-null terminated strings - Add support for '*', 'c', and 'u' flags in print formatting

arr committed 9 years ago

Commit 57e9d241 parent 3f81a2c4 files · +86 −44Browse files

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

Unified · Split

src/vm/array.cpp+12−4
@@ -171,18 +171,26 @@ void vm_array_t::copy_from(const vm_array_t &source, word_t this_begin_index) · 170 unmodified lines
171 171
172 auto dest_arr = _arr + (this_begin_index * _element_type->size_in_bytes);172 auto dest_arr = _arr + (this_begin_index * _element_type->size_in_bytes);
173 173
174 // Increment all pointers if we have reference types.174 // If we have reference types, increment references in the
175 // source array and decrement them in the destination array.
175 if (_element_type->map_in_bytes != 0)176 if (_element_type->map_in_bytes != 0)
176 {177 {
177 auto &type_desc = *_element_type;178 // [PERF] There is a chance this copy is within the same array, therefore
179 // a check could be made to not ref count memory that is going to be moved.
180 // The Inferno implementation of slicela handles this case (libinterp/xec.c).
181 const auto &type_desc = *_element_type;
178 auto source_array_element = source._arr;182 auto source_array_element = source._arr;
183 auto dest_array_element = dest_arr;
179 for (auto i = word_t{ 0 }; i < source._length; ++i)184 for (auto i = word_t{ 0 }; i < source._length; ++i)
180 {185 {
181 source_array_element += (i * type_desc.size_in_bytes);
182 inc_ref_count_in_memory(type_desc, source_array_element);186 inc_ref_count_in_memory(type_desc, source_array_element);
187 source_array_element += type_desc.size_in_bytes;
188
189 destroy_memory(type_desc, dest_array_element);
190 dest_array_element += type_desc.size_in_bytes;
183 }191 }
184 }192 }
185 193
186 // Moving data within the same array is permitted so use memmove().194 // Copy data from within the same array is permitted.
187 std::memmove(dest_arr, source._arr, (source._length * _element_type->size_in_bytes));195 std::memmove(dest_arr, source._arr, (source._length * _element_type->size_in_bytes));
188}196}