| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 | 140 |
| 141 | 141 |
| 142 MUST_USE_RESULT | 142 MUST_USE_RESULT |
| 143 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { | 143 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { |
| 144 return isolate->Throw<Object>( | 144 return isolate->Throw<Object>( |
| 145 isolate->factory()->NewRangeError("invalid_array_length", | 145 isolate->factory()->NewRangeError("invalid_array_length", |
| 146 HandleVector<Object>(NULL, 0))); | 146 HandleVector<Object>(NULL, 0))); |
| 147 } | 147 } |
| 148 | 148 |
| 149 | 149 |
| 150 static void CopyObjectToObjectElements(Handle<FixedArrayBase> from_base, | 150 static void CopyObjectToObjectElements(FixedArrayBase* from_base, |
| 151 ElementsKind from_kind, | 151 ElementsKind from_kind, |
| 152 uint32_t from_start, | 152 uint32_t from_start, |
| 153 Handle<FixedArrayBase> to_base, | 153 FixedArrayBase* to_base, |
| 154 ElementsKind to_kind, | 154 ElementsKind to_kind, uint32_t to_start, |
| 155 uint32_t to_start, | |
| 156 int raw_copy_size) { | 155 int raw_copy_size) { |
| 157 ASSERT(to_base->map() != | 156 ASSERT(to_base->map() != |
| 158 from_base->GetIsolate()->heap()->fixed_cow_array_map()); | 157 from_base->GetIsolate()->heap()->fixed_cow_array_map()); |
| 159 DisallowHeapAllocation no_allocation; | 158 DisallowHeapAllocation no_allocation; |
| 160 int copy_size = raw_copy_size; | 159 int copy_size = raw_copy_size; |
| 161 if (raw_copy_size < 0) { | 160 if (raw_copy_size < 0) { |
| 162 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 161 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 163 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 162 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 164 copy_size = Min(from_base->length() - from_start, | 163 copy_size = Min(from_base->length() - from_start, |
| 165 to_base->length() - to_start); | 164 to_base->length() - to_start); |
| 166 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 165 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 167 int start = to_start + copy_size; | 166 int start = to_start + copy_size; |
| 168 int length = to_base->length() - start; | 167 int length = to_base->length() - start; |
| 169 if (length > 0) { | 168 if (length > 0) { |
| 170 Heap* heap = from_base->GetHeap(); | 169 Heap* heap = from_base->GetHeap(); |
| 171 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, | 170 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
| 172 heap->the_hole_value(), length); | 171 heap->the_hole_value(), length); |
| 173 } | 172 } |
| 174 } | 173 } |
| 175 } | 174 } |
| 176 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 175 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 177 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 176 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 178 if (copy_size == 0) return; | 177 if (copy_size == 0) return; |
| 179 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); | 178 FixedArray* from = FixedArray::cast(from_base); |
| 180 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); | 179 FixedArray* to = FixedArray::cast(to_base); |
| 181 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); | 180 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); |
| 182 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 181 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
| 183 Address to_address = to->address() + FixedArray::kHeaderSize; | 182 Address to_address = to->address() + FixedArray::kHeaderSize; |
| 184 Address from_address = from->address() + FixedArray::kHeaderSize; | 183 Address from_address = from->address() + FixedArray::kHeaderSize; |
| 185 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, | 184 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, |
| 186 reinterpret_cast<Object**>(from_address) + from_start, | 185 reinterpret_cast<Object**>(from_address) + from_start, |
| 187 static_cast<size_t>(copy_size)); | 186 static_cast<size_t>(copy_size)); |
| 188 if (IsFastObjectElementsKind(from_kind) && | 187 if (IsFastObjectElementsKind(from_kind) && |
| 189 IsFastObjectElementsKind(to_kind)) { | 188 IsFastObjectElementsKind(to_kind)) { |
| 190 Heap* heap = from->GetHeap(); | 189 Heap* heap = from->GetHeap(); |
| 191 if (!heap->InNewSpace(*to)) { | 190 if (!heap->InNewSpace(to)) { |
| 192 heap->RecordWrites(to->address(), | 191 heap->RecordWrites(to->address(), |
| 193 to->OffsetOfElementAt(to_start), | 192 to->OffsetOfElementAt(to_start), |
| 194 copy_size); | 193 copy_size); |
| 195 } | 194 } |
| 196 heap->incremental_marking()->RecordWrites(*to); | 195 heap->incremental_marking()->RecordWrites(to); |
| 197 } | 196 } |
| 198 } | 197 } |
| 199 | 198 |
| 200 | 199 |
| 201 static void CopyDictionaryToObjectElements(Handle<FixedArrayBase> from_base, | 200 static void CopyDictionaryToObjectElements( |
| 202 uint32_t from_start, | 201 FixedArrayBase* from_base, uint32_t from_start, FixedArrayBase* to_base, |
| 203 Handle<FixedArrayBase> to_base, | 202 ElementsKind to_kind, uint32_t to_start, int raw_copy_size) { |
| 204 ElementsKind to_kind, | |
| 205 uint32_t to_start, | |
| 206 int raw_copy_size) { | |
| 207 Handle<SeededNumberDictionary> from = | |
| 208 Handle<SeededNumberDictionary>::cast(from_base); | |
| 209 DisallowHeapAllocation no_allocation; | 203 DisallowHeapAllocation no_allocation; |
| 204 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); |
| 210 int copy_size = raw_copy_size; | 205 int copy_size = raw_copy_size; |
| 211 Heap* heap = from->GetHeap(); | 206 Heap* heap = from->GetHeap(); |
| 212 if (raw_copy_size < 0) { | 207 if (raw_copy_size < 0) { |
| 213 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 208 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 214 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 209 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 215 copy_size = from->max_number_key() + 1 - from_start; | 210 copy_size = from->max_number_key() + 1 - from_start; |
| 216 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 211 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 217 int start = to_start + copy_size; | 212 int start = to_start + copy_size; |
| 218 int length = to_base->length() - start; | 213 int length = to_base->length() - start; |
| 219 if (length > 0) { | 214 if (length > 0) { |
| 220 Heap* heap = from->GetHeap(); | 215 Heap* heap = from->GetHeap(); |
| 221 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, | 216 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
| 222 heap->the_hole_value(), length); | 217 heap->the_hole_value(), length); |
| 223 } | 218 } |
| 224 } | 219 } |
| 225 } | 220 } |
| 226 ASSERT(*to_base != *from_base); | 221 ASSERT(to_base != from_base); |
| 227 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 222 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
| 228 if (copy_size == 0) return; | 223 if (copy_size == 0) return; |
| 229 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); | 224 FixedArray* to = FixedArray::cast(to_base); |
| 230 uint32_t to_length = to->length(); | 225 uint32_t to_length = to->length(); |
| 231 if (to_start + copy_size > to_length) { | 226 if (to_start + copy_size > to_length) { |
| 232 copy_size = to_length - to_start; | 227 copy_size = to_length - to_start; |
| 233 } | 228 } |
| 234 for (int i = 0; i < copy_size; i++) { | 229 for (int i = 0; i < copy_size; i++) { |
| 235 int entry = from->FindEntry(i + from_start); | 230 int entry = from->FindEntry(i + from_start); |
| 236 if (entry != SeededNumberDictionary::kNotFound) { | 231 if (entry != SeededNumberDictionary::kNotFound) { |
| 237 Object* value = from->ValueAt(entry); | 232 Object* value = from->ValueAt(entry); |
| 238 ASSERT(!value->IsTheHole()); | 233 ASSERT(!value->IsTheHole()); |
| 239 to->set(i + to_start, value, SKIP_WRITE_BARRIER); | 234 to->set(i + to_start, value, SKIP_WRITE_BARRIER); |
| 240 } else { | 235 } else { |
| 241 to->set_the_hole(i + to_start); | 236 to->set_the_hole(i + to_start); |
| 242 } | 237 } |
| 243 } | 238 } |
| 244 if (IsFastObjectElementsKind(to_kind)) { | 239 if (IsFastObjectElementsKind(to_kind)) { |
| 245 if (!heap->InNewSpace(*to)) { | 240 if (!heap->InNewSpace(to)) { |
| 246 heap->RecordWrites(to->address(), | 241 heap->RecordWrites(to->address(), |
| 247 to->OffsetOfElementAt(to_start), | 242 to->OffsetOfElementAt(to_start), |
| 248 copy_size); | 243 copy_size); |
| 249 } | 244 } |
| 250 heap->incremental_marking()->RecordWrites(*to); | 245 heap->incremental_marking()->RecordWrites(to); |
| 251 } | 246 } |
| 252 } | 247 } |
| 253 | 248 |
| 254 | 249 |
| 255 static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base, | 250 static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base, |
| 256 uint32_t from_start, | 251 uint32_t from_start, |
| 257 Handle<FixedArrayBase> to_base, | 252 Handle<FixedArrayBase> to_base, |
| 258 ElementsKind to_kind, | 253 ElementsKind to_kind, |
| 259 uint32_t to_start, | 254 uint32_t to_start, |
| 260 int raw_copy_size) { | 255 int raw_copy_size) { |
| 261 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 256 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
| 262 int copy_size = raw_copy_size; | 257 int copy_size = raw_copy_size; |
| 263 if (raw_copy_size < 0) { | 258 if (raw_copy_size < 0) { |
| 264 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 259 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 265 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 260 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 266 copy_size = Min(from_base->length() - from_start, | 261 copy_size = Min(from_base->length() - from_start, |
| 267 to_base->length() - to_start); | 262 to_base->length() - to_start); |
| 268 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 263 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 269 // Also initialize the area that will be copied over since HeapNumber | 264 // Also initialize the area that will be copied over since HeapNumber |
| 270 // allocation below can cause an incremental marking step, requiring all | 265 // allocation below can cause an incremental marking step, requiring all |
| 271 // existing heap objects to be propertly initialized. | 266 // existing heap objects to be propertly initialized. |
| 272 int start = to_start; | 267 int start = to_start; |
| 273 int length = to_base->length() - start; | 268 int length = to_base->length() - start; |
| 274 if (length > 0) { | 269 if (length > 0) { |
| 275 Heap* heap = from_base->GetHeap(); | 270 Heap* heap = from_base->GetHeap(); |
| 276 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, | 271 MemsetPointer(FixedArray::cast(*to_base)->data_start() + start, |
| 277 heap->the_hole_value(), length); | 272 heap->the_hole_value(), length); |
| 278 } | 273 } |
| 279 } | 274 } |
| 280 } | 275 } |
| 281 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 276 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 282 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 277 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 283 if (copy_size == 0) return; | 278 if (copy_size == 0) return; |
| 284 Isolate* isolate = from_base->GetIsolate(); | 279 Isolate* isolate = from_base->GetIsolate(); |
| 285 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); | 280 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); |
| 286 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); | 281 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
| 287 for (int i = 0; i < copy_size; ++i) { | 282 for (int i = 0; i < copy_size; ++i) { |
| 288 HandleScope scope(isolate); | 283 HandleScope scope(isolate); |
| 289 if (IsFastSmiElementsKind(to_kind)) { | 284 if (IsFastSmiElementsKind(to_kind)) { |
| 290 UNIMPLEMENTED(); | 285 UNIMPLEMENTED(); |
| 291 } else { | 286 } else { |
| 292 ASSERT(IsFastObjectElementsKind(to_kind)); | 287 ASSERT(IsFastObjectElementsKind(to_kind)); |
| 293 Handle<Object> value = FixedDoubleArray::get(from, i + from_start); | 288 Handle<Object> value = FixedDoubleArray::get(from, i + from_start); |
| 294 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); | 289 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); |
| 295 } | 290 } |
| 296 } | 291 } |
| 297 } | 292 } |
| 298 | 293 |
| 299 | 294 |
| 300 static void CopyDoubleToDoubleElements(Handle<FixedArrayBase> from_base, | 295 static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, |
| 301 uint32_t from_start, | 296 uint32_t from_start, |
| 302 Handle<FixedArrayBase> to_base, | 297 FixedArrayBase* to_base, |
| 303 uint32_t to_start, | 298 uint32_t to_start, int raw_copy_size) { |
| 304 int raw_copy_size) { | |
| 305 DisallowHeapAllocation no_allocation; | 299 DisallowHeapAllocation no_allocation; |
| 306 int copy_size = raw_copy_size; | 300 int copy_size = raw_copy_size; |
| 307 if (raw_copy_size < 0) { | 301 if (raw_copy_size < 0) { |
| 308 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 302 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 309 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 303 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 310 copy_size = Min(from_base->length() - from_start, | 304 copy_size = Min(from_base->length() - from_start, |
| 311 to_base->length() - to_start); | 305 to_base->length() - to_start); |
| 312 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 306 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 313 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 307 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 314 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); | 308 FixedDoubleArray::cast(to_base)->set_the_hole(i); |
| 315 } | 309 } |
| 316 } | 310 } |
| 317 } | 311 } |
| 318 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 312 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 319 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 313 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 320 if (copy_size == 0) return; | 314 if (copy_size == 0) return; |
| 321 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); | 315 FixedDoubleArray* from = FixedDoubleArray::cast(from_base); |
| 322 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); | 316 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
| 323 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; | 317 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
| 324 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; | 318 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
| 325 to_address += kDoubleSize * to_start; | 319 to_address += kDoubleSize * to_start; |
| 326 from_address += kDoubleSize * from_start; | 320 from_address += kDoubleSize * from_start; |
| 327 int words_per_double = (kDoubleSize / kPointerSize); | 321 int words_per_double = (kDoubleSize / kPointerSize); |
| 328 CopyWords(reinterpret_cast<Object**>(to_address), | 322 CopyWords(reinterpret_cast<Object**>(to_address), |
| 329 reinterpret_cast<Object**>(from_address), | 323 reinterpret_cast<Object**>(from_address), |
| 330 static_cast<size_t>(words_per_double * copy_size)); | 324 static_cast<size_t>(words_per_double * copy_size)); |
| 331 } | 325 } |
| 332 | 326 |
| 333 | 327 |
| 334 static void CopySmiToDoubleElements(Handle<FixedArrayBase> from_base, | 328 static void CopySmiToDoubleElements(FixedArrayBase* from_base, |
| 335 uint32_t from_start, | 329 uint32_t from_start, |
| 336 Handle<FixedArrayBase> to_base, | 330 FixedArrayBase* to_base, uint32_t to_start, |
| 337 uint32_t to_start, | |
| 338 int raw_copy_size) { | 331 int raw_copy_size) { |
| 339 DisallowHeapAllocation no_allocation; | 332 DisallowHeapAllocation no_allocation; |
| 340 int copy_size = raw_copy_size; | 333 int copy_size = raw_copy_size; |
| 341 if (raw_copy_size < 0) { | 334 if (raw_copy_size < 0) { |
| 342 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 335 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 343 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 336 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 344 copy_size = from_base->length() - from_start; | 337 copy_size = from_base->length() - from_start; |
| 345 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 338 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 346 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 339 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 347 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); | 340 FixedDoubleArray::cast(to_base)->set_the_hole(i); |
| 348 } | 341 } |
| 349 } | 342 } |
| 350 } | 343 } |
| 351 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 344 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 352 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 345 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 353 if (copy_size == 0) return; | 346 if (copy_size == 0) return; |
| 354 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); | 347 FixedArray* from = FixedArray::cast(from_base); |
| 355 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); | 348 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
| 356 Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value(); | 349 Object* the_hole = from->GetHeap()->the_hole_value(); |
| 357 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); | 350 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); |
| 358 from_start < from_end; from_start++, to_start++) { | 351 from_start < from_end; from_start++, to_start++) { |
| 359 Object* hole_or_smi = from->get(from_start); | 352 Object* hole_or_smi = from->get(from_start); |
| 360 if (hole_or_smi == *the_hole) { | 353 if (hole_or_smi == the_hole) { |
| 361 to->set_the_hole(to_start); | 354 to->set_the_hole(to_start); |
| 362 } else { | 355 } else { |
| 363 to->set(to_start, Smi::cast(hole_or_smi)->value()); | 356 to->set(to_start, Smi::cast(hole_or_smi)->value()); |
| 364 } | 357 } |
| 365 } | 358 } |
| 366 } | 359 } |
| 367 | 360 |
| 368 | 361 |
| 369 static void CopyPackedSmiToDoubleElements(Handle<FixedArrayBase> from_base, | 362 static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, |
| 370 uint32_t from_start, | 363 uint32_t from_start, |
| 371 Handle<FixedArrayBase> to_base, | 364 FixedArrayBase* to_base, |
| 372 uint32_t to_start, | 365 uint32_t to_start, int packed_size, |
| 373 int packed_size, | |
| 374 int raw_copy_size) { | 366 int raw_copy_size) { |
| 375 DisallowHeapAllocation no_allocation; | 367 DisallowHeapAllocation no_allocation; |
| 376 int copy_size = raw_copy_size; | 368 int copy_size = raw_copy_size; |
| 377 uint32_t to_end; | 369 uint32_t to_end; |
| 378 if (raw_copy_size < 0) { | 370 if (raw_copy_size < 0) { |
| 379 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 371 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 380 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 372 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 381 copy_size = packed_size - from_start; | 373 copy_size = packed_size - from_start; |
| 382 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 374 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 383 to_end = to_base->length(); | 375 to_end = to_base->length(); |
| 384 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { | 376 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { |
| 385 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); | 377 FixedDoubleArray::cast(to_base)->set_the_hole(i); |
| 386 } | 378 } |
| 387 } else { | 379 } else { |
| 388 to_end = to_start + static_cast<uint32_t>(copy_size); | 380 to_end = to_start + static_cast<uint32_t>(copy_size); |
| 389 } | 381 } |
| 390 } else { | 382 } else { |
| 391 to_end = to_start + static_cast<uint32_t>(copy_size); | 383 to_end = to_start + static_cast<uint32_t>(copy_size); |
| 392 } | 384 } |
| 393 ASSERT(static_cast<int>(to_end) <= to_base->length()); | 385 ASSERT(static_cast<int>(to_end) <= to_base->length()); |
| 394 ASSERT(packed_size >= 0 && packed_size <= copy_size); | 386 ASSERT(packed_size >= 0 && packed_size <= copy_size); |
| 395 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 387 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 396 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 388 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 397 if (copy_size == 0) return; | 389 if (copy_size == 0) return; |
| 398 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); | 390 FixedArray* from = FixedArray::cast(from_base); |
| 399 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); | 391 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
| 400 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); | 392 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
| 401 from_start < from_end; from_start++, to_start++) { | 393 from_start < from_end; from_start++, to_start++) { |
| 402 Object* smi = from->get(from_start); | 394 Object* smi = from->get(from_start); |
| 403 ASSERT(!smi->IsTheHole()); | 395 ASSERT(!smi->IsTheHole()); |
| 404 to->set(to_start, Smi::cast(smi)->value()); | 396 to->set(to_start, Smi::cast(smi)->value()); |
| 405 } | 397 } |
| 406 } | 398 } |
| 407 | 399 |
| 408 | 400 |
| 409 static void CopyObjectToDoubleElements(Handle<FixedArrayBase> from_base, | 401 static void CopyObjectToDoubleElements(FixedArrayBase* from_base, |
| 410 uint32_t from_start, | 402 uint32_t from_start, |
| 411 Handle<FixedArrayBase> to_base, | 403 FixedArrayBase* to_base, |
| 412 uint32_t to_start, | 404 uint32_t to_start, int raw_copy_size) { |
| 413 int raw_copy_size) { | |
| 414 DisallowHeapAllocation no_allocation; | 405 DisallowHeapAllocation no_allocation; |
| 415 int copy_size = raw_copy_size; | 406 int copy_size = raw_copy_size; |
| 416 if (raw_copy_size < 0) { | 407 if (raw_copy_size < 0) { |
| 417 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 408 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 418 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 409 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 419 copy_size = from_base->length() - from_start; | 410 copy_size = from_base->length() - from_start; |
| 420 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 411 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 421 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 412 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 422 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); | 413 FixedDoubleArray::cast(to_base)->set_the_hole(i); |
| 423 } | 414 } |
| 424 } | 415 } |
| 425 } | 416 } |
| 426 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 417 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 427 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 418 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 428 if (copy_size == 0) return; | 419 if (copy_size == 0) return; |
| 429 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); | 420 FixedArray* from = FixedArray::cast(from_base); |
| 430 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); | 421 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
| 431 Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value(); | 422 Object* the_hole = from->GetHeap()->the_hole_value(); |
| 432 for (uint32_t from_end = from_start + copy_size; | 423 for (uint32_t from_end = from_start + copy_size; |
| 433 from_start < from_end; from_start++, to_start++) { | 424 from_start < from_end; from_start++, to_start++) { |
| 434 Object* hole_or_object = from->get(from_start); | 425 Object* hole_or_object = from->get(from_start); |
| 435 if (hole_or_object == *the_hole) { | 426 if (hole_or_object == the_hole) { |
| 436 to->set_the_hole(to_start); | 427 to->set_the_hole(to_start); |
| 437 } else { | 428 } else { |
| 438 to->set(to_start, hole_or_object->Number()); | 429 to->set(to_start, hole_or_object->Number()); |
| 439 } | 430 } |
| 440 } | 431 } |
| 441 } | 432 } |
| 442 | 433 |
| 443 | 434 |
| 444 static void CopyDictionaryToDoubleElements(Handle<FixedArrayBase> from_base, | 435 static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base, |
| 445 uint32_t from_start, | 436 uint32_t from_start, |
| 446 Handle<FixedArrayBase> to_base, | 437 FixedArrayBase* to_base, |
| 447 uint32_t to_start, | 438 uint32_t to_start, |
| 448 int raw_copy_size) { | 439 int raw_copy_size) { |
| 449 Handle<SeededNumberDictionary> from = | |
| 450 Handle<SeededNumberDictionary>::cast(from_base); | |
| 451 DisallowHeapAllocation no_allocation; | 440 DisallowHeapAllocation no_allocation; |
| 441 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); |
| 452 int copy_size = raw_copy_size; | 442 int copy_size = raw_copy_size; |
| 453 if (copy_size < 0) { | 443 if (copy_size < 0) { |
| 454 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || | 444 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
| 455 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 445 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 456 copy_size = from->max_number_key() + 1 - from_start; | 446 copy_size = from->max_number_key() + 1 - from_start; |
| 457 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 447 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 458 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 448 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 459 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); | 449 FixedDoubleArray::cast(to_base)->set_the_hole(i); |
| 460 } | 450 } |
| 461 } | 451 } |
| 462 } | 452 } |
| 463 if (copy_size == 0) return; | 453 if (copy_size == 0) return; |
| 464 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); | 454 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
| 465 uint32_t to_length = to->length(); | 455 uint32_t to_length = to->length(); |
| 466 if (to_start + copy_size > to_length) { | 456 if (to_start + copy_size > to_length) { |
| 467 copy_size = to_length - to_start; | 457 copy_size = to_length - to_start; |
| 468 } | 458 } |
| 469 for (int i = 0; i < copy_size; i++) { | 459 for (int i = 0; i < copy_size; i++) { |
| 470 int entry = from->FindEntry(i + from_start); | 460 int entry = from->FindEntry(i + from_start); |
| 471 if (entry != SeededNumberDictionary::kNotFound) { | 461 if (entry != SeededNumberDictionary::kNotFound) { |
| 472 to->set(i + to_start, from->ValueAt(entry)->Number()); | 462 to->set(i + to_start, from->ValueAt(entry)->Number()); |
| 473 } else { | 463 } else { |
| 474 to->set_the_hole(i + to_start); | 464 to->set_the_hole(i + to_start); |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 ElementsKind from_kind, | 1099 ElementsKind from_kind, |
| 1110 uint32_t to_start, | 1100 uint32_t to_start, |
| 1111 int packed_size, | 1101 int packed_size, |
| 1112 int copy_size) { | 1102 int copy_size) { |
| 1113 ElementsKind to_kind = KindTraits::Kind; | 1103 ElementsKind to_kind = KindTraits::Kind; |
| 1114 switch (from_kind) { | 1104 switch (from_kind) { |
| 1115 case FAST_SMI_ELEMENTS: | 1105 case FAST_SMI_ELEMENTS: |
| 1116 case FAST_HOLEY_SMI_ELEMENTS: | 1106 case FAST_HOLEY_SMI_ELEMENTS: |
| 1117 case FAST_ELEMENTS: | 1107 case FAST_ELEMENTS: |
| 1118 case FAST_HOLEY_ELEMENTS: | 1108 case FAST_HOLEY_ELEMENTS: |
| 1119 CopyObjectToObjectElements( | 1109 CopyObjectToObjectElements(*from, from_kind, from_start, *to, to_kind, |
| 1120 from, from_kind, from_start, to, to_kind, to_start, copy_size); | 1110 to_start, copy_size); |
| 1121 break; | 1111 break; |
| 1122 case FAST_DOUBLE_ELEMENTS: | 1112 case FAST_DOUBLE_ELEMENTS: |
| 1123 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1113 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 1124 CopyDoubleToObjectElements( | 1114 CopyDoubleToObjectElements( |
| 1125 from, from_start, to, to_kind, to_start, copy_size); | 1115 from, from_start, to, to_kind, to_start, copy_size); |
| 1126 break; | 1116 break; |
| 1127 case DICTIONARY_ELEMENTS: | 1117 case DICTIONARY_ELEMENTS: |
| 1128 CopyDictionaryToObjectElements( | 1118 CopyDictionaryToObjectElements(*from, from_start, *to, to_kind, |
| 1129 from, from_start, to, to_kind, to_start, copy_size); | 1119 to_start, copy_size); |
| 1130 break; | 1120 break; |
| 1131 case SLOPPY_ARGUMENTS_ELEMENTS: { | 1121 case SLOPPY_ARGUMENTS_ELEMENTS: { |
| 1132 // TODO(verwaest): This is a temporary hack to support extending | 1122 // TODO(verwaest): This is a temporary hack to support extending |
| 1133 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. | 1123 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. |
| 1134 // This case should be UNREACHABLE(). | 1124 // This case should be UNREACHABLE(). |
| 1135 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); | 1125 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); |
| 1136 Handle<FixedArrayBase> arguments( | 1126 Handle<FixedArrayBase> arguments( |
| 1137 FixedArrayBase::cast(parameter_map->get(1))); | 1127 FixedArrayBase::cast(parameter_map->get(1))); |
| 1138 ElementsKind from_kind = ElementsKindForArray(arguments); | 1128 ElementsKind from_kind = ElementsKindForArray(arguments); |
| 1139 CopyElementsImpl(arguments, from_start, to, from_kind, | 1129 CopyElementsImpl(arguments, from_start, to, from_kind, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 protected: | 1223 protected: |
| 1234 static void CopyElementsImpl(Handle<FixedArrayBase> from, | 1224 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
| 1235 uint32_t from_start, | 1225 uint32_t from_start, |
| 1236 Handle<FixedArrayBase> to, | 1226 Handle<FixedArrayBase> to, |
| 1237 ElementsKind from_kind, | 1227 ElementsKind from_kind, |
| 1238 uint32_t to_start, | 1228 uint32_t to_start, |
| 1239 int packed_size, | 1229 int packed_size, |
| 1240 int copy_size) { | 1230 int copy_size) { |
| 1241 switch (from_kind) { | 1231 switch (from_kind) { |
| 1242 case FAST_SMI_ELEMENTS: | 1232 case FAST_SMI_ELEMENTS: |
| 1243 CopyPackedSmiToDoubleElements( | 1233 CopyPackedSmiToDoubleElements(*from, from_start, *to, to_start, |
| 1244 from, from_start, to, to_start, packed_size, copy_size); | 1234 packed_size, copy_size); |
| 1245 break; | 1235 break; |
| 1246 case FAST_HOLEY_SMI_ELEMENTS: | 1236 case FAST_HOLEY_SMI_ELEMENTS: |
| 1247 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); | 1237 CopySmiToDoubleElements(*from, from_start, *to, to_start, copy_size); |
| 1248 break; | 1238 break; |
| 1249 case FAST_DOUBLE_ELEMENTS: | 1239 case FAST_DOUBLE_ELEMENTS: |
| 1250 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1240 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 1251 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size); | 1241 CopyDoubleToDoubleElements(*from, from_start, *to, to_start, copy_size); |
| 1252 break; | 1242 break; |
| 1253 case FAST_ELEMENTS: | 1243 case FAST_ELEMENTS: |
| 1254 case FAST_HOLEY_ELEMENTS: | 1244 case FAST_HOLEY_ELEMENTS: |
| 1255 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); | 1245 CopyObjectToDoubleElements(*from, from_start, *to, to_start, copy_size); |
| 1256 break; | 1246 break; |
| 1257 case DICTIONARY_ELEMENTS: | 1247 case DICTIONARY_ELEMENTS: |
| 1258 CopyDictionaryToDoubleElements( | 1248 CopyDictionaryToDoubleElements(*from, from_start, *to, to_start, |
| 1259 from, from_start, to, to_start, copy_size); | 1249 copy_size); |
| 1260 break; | 1250 break; |
| 1261 case SLOPPY_ARGUMENTS_ELEMENTS: | 1251 case SLOPPY_ARGUMENTS_ELEMENTS: |
| 1262 UNREACHABLE(); | 1252 UNREACHABLE(); |
| 1263 | 1253 |
| 1264 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1254 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 1265 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1255 case EXTERNAL_##TYPE##_ELEMENTS: \ |
| 1266 case TYPE##_ELEMENTS: \ | 1256 case TYPE##_ELEMENTS: \ |
| 1267 UNREACHABLE(); | 1257 UNREACHABLE(); |
| 1268 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1258 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 1269 #undef TYPED_ARRAY_CASE | 1259 #undef TYPED_ARRAY_CASE |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1990 UNREACHABLE(); | 1980 UNREACHABLE(); |
| 1991 break; | 1981 break; |
| 1992 } | 1982 } |
| 1993 | 1983 |
| 1994 array->set_elements(*elms); | 1984 array->set_elements(*elms); |
| 1995 array->set_length(Smi::FromInt(number_of_elements)); | 1985 array->set_length(Smi::FromInt(number_of_elements)); |
| 1996 return array; | 1986 return array; |
| 1997 } | 1987 } |
| 1998 | 1988 |
| 1999 } } // namespace v8::internal | 1989 } } // namespace v8::internal |
| OLD | NEW |