Showing the changes to src/vm/array.cpp (1 of 4 files). Show all
Unified · Split
| @@ -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 | } |