| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 8430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8441 } | 8441 } |
| 8442 } | 8442 } |
| 8443 | 8443 |
| 8444 PrintF("RelocInfo (size = %d)\n", relocation_size()); | 8444 PrintF("RelocInfo (size = %d)\n", relocation_size()); |
| 8445 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); | 8445 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); |
| 8446 PrintF(out, "\n"); | 8446 PrintF(out, "\n"); |
| 8447 } | 8447 } |
| 8448 #endif // ENABLE_DISASSEMBLER | 8448 #endif // ENABLE_DISASSEMBLER |
| 8449 | 8449 |
| 8450 | 8450 |
| 8451 static void CopyFastElementsToFast(FixedArray* source, | |
| 8452 FixedArray* destination, | |
| 8453 WriteBarrierMode mode) { | |
| 8454 int count = source->length(); | |
| 8455 int copy_size = Min(count, destination->length()); | |
| 8456 if (mode == SKIP_WRITE_BARRIER || | |
| 8457 !Page::FromAddress(destination->address())->IsFlagSet( | |
| 8458 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)) { | |
| 8459 Address to = destination->address() + FixedArray::kHeaderSize; | |
| 8460 Address from = source->address() + FixedArray::kHeaderSize; | |
| 8461 memcpy(reinterpret_cast<void*>(to), | |
| 8462 reinterpret_cast<void*>(from), | |
| 8463 kPointerSize * copy_size); | |
| 8464 } else { | |
| 8465 for (int i = 0; i < copy_size; ++i) { | |
| 8466 destination->set(i, source->get(i), mode); | |
| 8467 } | |
| 8468 } | |
| 8469 } | |
| 8470 | |
| 8471 | |
| 8472 static void CopySlowElementsToFast(SeededNumberDictionary* source, | |
| 8473 FixedArray* destination, | |
| 8474 WriteBarrierMode mode) { | |
| 8475 int destination_length = destination->length(); | |
| 8476 for (int i = 0; i < source->Capacity(); ++i) { | |
| 8477 Object* key = source->KeyAt(i); | |
| 8478 if (key->IsNumber()) { | |
| 8479 uint32_t entry = static_cast<uint32_t>(key->Number()); | |
| 8480 if (entry < static_cast<uint32_t>(destination_length)) { | |
| 8481 destination->set(entry, source->ValueAt(i), mode); | |
| 8482 } | |
| 8483 } | |
| 8484 } | |
| 8485 } | |
| 8486 | |
| 8487 | |
| 8488 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 8451 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
| 8489 int capacity, | 8452 int capacity, |
| 8490 int length, | 8453 int length, |
| 8491 SetFastElementsCapacityMode set_capacity_mode) { | 8454 SetFastElementsCapacityMode set_capacity_mode) { |
| 8492 Heap* heap = GetHeap(); | 8455 Heap* heap = GetHeap(); |
| 8493 // We should never end in here with a pixel or external array. | 8456 // We should never end in here with a pixel or external array. |
| 8494 ASSERT(!HasExternalArrayElements()); | 8457 ASSERT(!HasExternalArrayElements()); |
| 8495 | 8458 |
| 8496 // Allocate a new fast elements backing store. | 8459 // Allocate a new fast elements backing store. |
| 8497 FixedArray* new_elements; | 8460 FixedArray* new_elements; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 8511 elements() == heap->empty_fixed_array())); | 8474 elements() == heap->empty_fixed_array())); |
| 8512 ElementsKind elements_kind = has_fast_smi_only_elements | 8475 ElementsKind elements_kind = has_fast_smi_only_elements |
| 8513 ? FAST_SMI_ONLY_ELEMENTS | 8476 ? FAST_SMI_ONLY_ELEMENTS |
| 8514 : FAST_ELEMENTS; | 8477 : FAST_ELEMENTS; |
| 8515 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); | 8478 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); |
| 8516 if (!maybe->To(&new_map)) return maybe; | 8479 if (!maybe->To(&new_map)) return maybe; |
| 8517 } | 8480 } |
| 8518 | 8481 |
| 8519 FixedArrayBase* old_elements_raw = elements(); | 8482 FixedArrayBase* old_elements_raw = elements(); |
| 8520 ElementsKind elements_kind = GetElementsKind(); | 8483 ElementsKind elements_kind = GetElementsKind(); |
| 8521 switch (elements_kind) { | 8484 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); |
| 8522 case FAST_SMI_ONLY_ELEMENTS: | 8485 ElementsKind to_kind = (elements_kind == FAST_SMI_ONLY_ELEMENTS) |
| 8523 case FAST_ELEMENTS: { | 8486 ? FAST_SMI_ONLY_ELEMENTS |
| 8524 AssertNoAllocation no_gc; | 8487 : FAST_ELEMENTS; |
| 8525 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); | 8488 // int copy_size = Min(old_elements_raw->length(), new_elements->length()); |
| 8526 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), | 8489 accessor->CopyElements(this, new_elements, to_kind); |
| 8527 new_elements, mode); | 8490 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { |
| 8528 set_map_and_elements(new_map, new_elements); | 8491 set_map_and_elements(new_map, new_elements); |
| 8529 break; | 8492 } else { |
| 8530 } | 8493 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); |
| 8531 case DICTIONARY_ELEMENTS: { | 8494 parameter_map->set(1, new_elements); |
| 8532 AssertNoAllocation no_gc; | |
| 8533 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | |
| 8534 CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw), | |
| 8535 new_elements, | |
| 8536 mode); | |
| 8537 set_map_and_elements(new_map, new_elements); | |
| 8538 break; | |
| 8539 } | |
| 8540 case NON_STRICT_ARGUMENTS_ELEMENTS: { | |
| 8541 AssertNoAllocation no_gc; | |
| 8542 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | |
| 8543 // The object's map and the parameter map are unchanged, the unaliased | |
| 8544 // arguments are copied to the new backing store. | |
| 8545 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); | |
| 8546 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 8547 if (arguments->IsDictionary()) { | |
| 8548 CopySlowElementsToFast(SeededNumberDictionary::cast(arguments), | |
| 8549 new_elements, | |
| 8550 mode); | |
| 8551 } else { | |
| 8552 CopyFastElementsToFast(arguments, new_elements, mode); | |
| 8553 } | |
| 8554 parameter_map->set(1, new_elements); | |
| 8555 break; | |
| 8556 } | |
| 8557 case FAST_DOUBLE_ELEMENTS: { | |
| 8558 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw); | |
| 8559 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); | |
| 8560 // Fill out the new array with this content and array holes. | |
| 8561 for (uint32_t i = 0; i < old_length; i++) { | |
| 8562 if (!old_elements->is_the_hole(i)) { | |
| 8563 Object* obj; | |
| 8564 // Objects must be allocated in the old object space, since the | |
| 8565 // overall number of HeapNumbers needed for the conversion might | |
| 8566 // exceed the capacity of new space, and we would fail repeatedly | |
| 8567 // trying to convert the FixedDoubleArray. | |
| 8568 MaybeObject* maybe_value_object = | |
| 8569 GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i), | |
| 8570 TENURED); | |
| 8571 if (!maybe_value_object->To(&obj)) return maybe_value_object; | |
| 8572 // Force write barrier. It's not worth trying to exploit | |
| 8573 // elems->GetWriteBarrierMode(), since it requires an | |
| 8574 // AssertNoAllocation stack object that would have to be positioned | |
| 8575 // after the HeapNumber allocation anyway. | |
| 8576 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); | |
| 8577 } | |
| 8578 } | |
| 8579 set_map(new_map); | |
| 8580 set_elements(new_elements); | |
| 8581 break; | |
| 8582 } | |
| 8583 case EXTERNAL_BYTE_ELEMENTS: | |
| 8584 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 8585 case EXTERNAL_SHORT_ELEMENTS: | |
| 8586 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 8587 case EXTERNAL_INT_ELEMENTS: | |
| 8588 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 8589 case EXTERNAL_FLOAT_ELEMENTS: | |
| 8590 case EXTERNAL_DOUBLE_ELEMENTS: | |
| 8591 case EXTERNAL_PIXEL_ELEMENTS: | |
| 8592 UNREACHABLE(); | |
| 8593 break; | |
| 8594 } | 8495 } |
| 8595 | 8496 |
| 8596 if (FLAG_trace_elements_transitions) { | 8497 if (FLAG_trace_elements_transitions) { |
| 8597 PrintElementsTransition(stdout, elements_kind, old_elements_raw, | 8498 PrintElementsTransition(stdout, elements_kind, old_elements_raw, |
| 8598 GetElementsKind(), new_elements); | 8499 GetElementsKind(), new_elements); |
| 8599 } | 8500 } |
| 8600 | 8501 |
| 8601 // Update the length if necessary. | 8502 // Update the length if necessary. |
| 8602 if (IsJSArray()) { | 8503 if (IsJSArray()) { |
| 8603 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 8504 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
| (...skipping 4353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12957 if (break_point_objects()->IsUndefined()) return 0; | 12858 if (break_point_objects()->IsUndefined()) return 0; |
| 12958 // Single break point. | 12859 // Single break point. |
| 12959 if (!break_point_objects()->IsFixedArray()) return 1; | 12860 if (!break_point_objects()->IsFixedArray()) return 1; |
| 12960 // Multiple break points. | 12861 // Multiple break points. |
| 12961 return FixedArray::cast(break_point_objects())->length(); | 12862 return FixedArray::cast(break_point_objects())->length(); |
| 12962 } | 12863 } |
| 12963 #endif // ENABLE_DEBUGGER_SUPPORT | 12864 #endif // ENABLE_DEBUGGER_SUPPORT |
| 12964 | 12865 |
| 12965 | 12866 |
| 12966 } } // namespace v8::internal | 12867 } } // namespace v8::internal |
| OLD | NEW |