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 |