| 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 5746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5757 // Transitions are only kept when inserting another transition. | 5757 // Transitions are only kept when inserting another transition. |
| 5758 // This precondition is not required by this function's implementation, but | 5758 // This precondition is not required by this function's implementation, but |
| 5759 // is currently required by the semantics of maps, so we check it. | 5759 // is currently required by the semantics of maps, so we check it. |
| 5760 // Conversely, we filter after replacing, so replacing a transition and | 5760 // Conversely, we filter after replacing, so replacing a transition and |
| 5761 // removing all other transitions is not supported. | 5761 // removing all other transitions is not supported. |
| 5762 bool remove_transitions = transition_flag == REMOVE_TRANSITIONS; | 5762 bool remove_transitions = transition_flag == REMOVE_TRANSITIONS; |
| 5763 ASSERT(remove_transitions == !descriptor->ContainsTransition()); | 5763 ASSERT(remove_transitions == !descriptor->ContainsTransition()); |
| 5764 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); | 5764 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); |
| 5765 | 5765 |
| 5766 // Ensure the key is a symbol. | 5766 // Ensure the key is a symbol. |
| 5767 Object* result; | |
| 5768 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 5767 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
| 5769 if (!maybe_result->ToObject(&result)) return maybe_result; | 5768 if (maybe_result->IsFailure()) return maybe_result; |
| 5770 } | 5769 } |
| 5771 | 5770 |
| 5772 int new_size = 0; | 5771 int new_size = 0; |
| 5773 for (int i = 0; i < number_of_descriptors(); i++) { | 5772 for (int i = 0; i < number_of_descriptors(); i++) { |
| 5774 if (IsNullDescriptor(i)) continue; | 5773 if (IsNullDescriptor(i)) continue; |
| 5775 if (remove_transitions && IsTransitionOnly(i)) continue; | 5774 if (remove_transitions && IsTransitionOnly(i)) continue; |
| 5776 new_size++; | 5775 new_size++; |
| 5777 } | 5776 } |
| 5778 | 5777 |
| 5779 // If key is in descriptor, we replace it in-place when filtering. | 5778 // If key is in descriptor, we replace it in-place when filtering. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5794 // Replaced descriptor has been counted as removed if it is | 5793 // Replaced descriptor has been counted as removed if it is |
| 5795 // a transition that will be replaced. Adjust count in this case. | 5794 // a transition that will be replaced. Adjust count in this case. |
| 5796 ++new_size; | 5795 ++new_size; |
| 5797 } | 5796 } |
| 5798 } else { | 5797 } else { |
| 5799 ++new_size; | 5798 ++new_size; |
| 5800 } | 5799 } |
| 5801 | 5800 |
| 5802 DescriptorArray* new_descriptors; | 5801 DescriptorArray* new_descriptors; |
| 5803 { MaybeObject* maybe_result = Allocate(new_size); | 5802 { MaybeObject* maybe_result = Allocate(new_size); |
| 5804 if (!maybe_result->To<DescriptorArray>(&new_descriptors)) { | 5803 if (!maybe_result->To(&new_descriptors)) return maybe_result; |
| 5805 return maybe_result; | |
| 5806 } | |
| 5807 } | 5804 } |
| 5808 | 5805 |
| 5809 DescriptorArray::WhitenessWitness witness(new_descriptors); | 5806 DescriptorArray::WhitenessWitness witness(new_descriptors); |
| 5810 | 5807 |
| 5811 // Set the enumeration index in the descriptors and set the enumeration index | 5808 // Set the enumeration index in the descriptors and set the enumeration index |
| 5812 // in the result. | 5809 // in the result. |
| 5813 int enumeration_index = NextEnumerationIndex(); | 5810 int enumeration_index = NextEnumerationIndex(); |
| 5814 if (!descriptor->ContainsTransition()) { | 5811 if (!descriptor->ContainsTransition()) { |
| 5815 if (keep_enumeration_index) { | 5812 if (keep_enumeration_index) { |
| 5816 descriptor->SetEnumerationIndex( | 5813 descriptor->SetEnumerationIndex( |
| (...skipping 29 matching lines...) Expand all Loading... |
| 5846 new_descriptors->Set(insertion_index, descriptor, witness); | 5843 new_descriptors->Set(insertion_index, descriptor, witness); |
| 5847 | 5844 |
| 5848 ASSERT(to_index == new_descriptors->number_of_descriptors()); | 5845 ASSERT(to_index == new_descriptors->number_of_descriptors()); |
| 5849 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | 5846 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
| 5850 | 5847 |
| 5851 return new_descriptors; | 5848 return new_descriptors; |
| 5852 } | 5849 } |
| 5853 | 5850 |
| 5854 | 5851 |
| 5855 MaybeObject* DescriptorArray::RemoveTransitions() { | 5852 MaybeObject* DescriptorArray::RemoveTransitions() { |
| 5856 // Remove all transitions and null descriptors. Return a copy of the array | 5853 // Allocate the new descriptor array. |
| 5857 // with all transitions removed, or a Failure object if the new array could | |
| 5858 // not be allocated. | |
| 5859 | |
| 5860 // Compute the size of the map transition entries to be removed. | |
| 5861 int new_number_of_descriptors = 0; | 5854 int new_number_of_descriptors = 0; |
| 5862 for (int i = 0; i < number_of_descriptors(); i++) { | 5855 for (int i = 0; i < number_of_descriptors(); i++) { |
| 5863 if (IsProperty(i)) new_number_of_descriptors++; | 5856 if (IsProperty(i)) new_number_of_descriptors++; |
| 5864 } | 5857 } |
| 5865 | |
| 5866 // Allocate the new descriptor array. | |
| 5867 DescriptorArray* new_descriptors; | 5858 DescriptorArray* new_descriptors; |
| 5868 { MaybeObject* maybe_result = Allocate(new_number_of_descriptors); | 5859 { MaybeObject* maybe_result = Allocate(new_number_of_descriptors); |
| 5869 if (!maybe_result->To<DescriptorArray>(&new_descriptors)) { | 5860 if (!maybe_result->To(&new_descriptors)) return maybe_result; |
| 5870 return maybe_result; | |
| 5871 } | |
| 5872 } | 5861 } |
| 5873 | 5862 |
| 5863 // Copy the content. |
| 5874 DescriptorArray::WhitenessWitness witness(new_descriptors); | 5864 DescriptorArray::WhitenessWitness witness(new_descriptors); |
| 5875 | |
| 5876 // Copy the content. | |
| 5877 int next_descriptor = 0; | 5865 int next_descriptor = 0; |
| 5878 for (int i = 0; i < number_of_descriptors(); i++) { | 5866 for (int i = 0; i < number_of_descriptors(); i++) { |
| 5879 if (IsProperty(i)) { | 5867 if (IsProperty(i)) { |
| 5880 MaybeObject* copy_result = | 5868 MaybeObject* copy_result = |
| 5881 new_descriptors->CopyFrom(next_descriptor++, this, i, witness); | 5869 new_descriptors->CopyFrom(next_descriptor++, this, i, witness); |
| 5882 if (copy_result->IsFailure()) return copy_result; | 5870 if (copy_result->IsFailure()) return copy_result; |
| 5883 } | 5871 } |
| 5884 } | 5872 } |
| 5885 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); | 5873 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); |
| 5886 | 5874 |
| (...skipping 1680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7567 Object* construct_prototype = value; | 7555 Object* construct_prototype = value; |
| 7568 | 7556 |
| 7569 // If the value is not a JSObject, store the value in the map's | 7557 // If the value is not a JSObject, store the value in the map's |
| 7570 // constructor field so it can be accessed. Also, set the prototype | 7558 // constructor field so it can be accessed. Also, set the prototype |
| 7571 // used for constructing objects to the original object prototype. | 7559 // used for constructing objects to the original object prototype. |
| 7572 // See ECMA-262 13.2.2. | 7560 // See ECMA-262 13.2.2. |
| 7573 if (!value->IsJSObject()) { | 7561 if (!value->IsJSObject()) { |
| 7574 // Copy the map so this does not affect unrelated functions. | 7562 // Copy the map so this does not affect unrelated functions. |
| 7575 // Remove map transitions because they point to maps with a | 7563 // Remove map transitions because they point to maps with a |
| 7576 // different prototype. | 7564 // different prototype. |
| 7577 Object* new_object; | 7565 Map* new_map; |
| 7578 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); | 7566 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); |
| 7579 if (!maybe_new_map->ToObject(&new_object)) return maybe_new_map; | 7567 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 7580 } | 7568 } |
| 7581 Map* new_map = Map::cast(new_object); | |
| 7582 Heap* heap = new_map->GetHeap(); | 7569 Heap* heap = new_map->GetHeap(); |
| 7583 set_map(new_map); | 7570 set_map(new_map); |
| 7584 new_map->set_constructor(value); | 7571 new_map->set_constructor(value); |
| 7585 new_map->set_non_instance_prototype(true); | 7572 new_map->set_non_instance_prototype(true); |
| 7586 construct_prototype = | 7573 construct_prototype = |
| 7587 heap->isolate()->context()->global_context()-> | 7574 heap->isolate()->context()->global_context()-> |
| 7588 initial_object_prototype(); | 7575 initial_object_prototype(); |
| 7589 } else { | 7576 } else { |
| 7590 map()->set_non_instance_prototype(false); | 7577 map()->set_non_instance_prototype(false); |
| 7591 } | 7578 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7628 | 7615 |
| 7629 | 7616 |
| 7630 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { | 7617 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { |
| 7631 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); | 7618 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); |
| 7632 } | 7619 } |
| 7633 | 7620 |
| 7634 | 7621 |
| 7635 MaybeObject* Oddball::Initialize(const char* to_string, | 7622 MaybeObject* Oddball::Initialize(const char* to_string, |
| 7636 Object* to_number, | 7623 Object* to_number, |
| 7637 byte kind) { | 7624 byte kind) { |
| 7638 Object* symbol; | 7625 String* symbol; |
| 7639 { MaybeObject* maybe_symbol = | 7626 { MaybeObject* maybe_symbol = |
| 7640 Isolate::Current()->heap()->LookupAsciiSymbol(to_string); | 7627 Isolate::Current()->heap()->LookupAsciiSymbol(to_string); |
| 7641 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; | 7628 if (!maybe_symbol->To(&symbol)) return maybe_symbol; |
| 7642 } | 7629 } |
| 7643 set_to_string(String::cast(symbol)); | 7630 set_to_string(symbol); |
| 7644 set_to_number(to_number); | 7631 set_to_number(to_number); |
| 7645 set_kind(kind); | 7632 set_kind(kind); |
| 7646 return this; | 7633 return this; |
| 7647 } | 7634 } |
| 7648 | 7635 |
| 7649 | 7636 |
| 7650 String* SharedFunctionInfo::DebugName() { | 7637 String* SharedFunctionInfo::DebugName() { |
| 7651 Object* n = name(); | 7638 Object* n = name(); |
| 7652 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); | 7639 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); |
| 7653 return String::cast(n); | 7640 return String::cast(n); |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8545 | 8532 |
| 8546 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 8533 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
| 8547 int capacity, | 8534 int capacity, |
| 8548 int length, | 8535 int length, |
| 8549 SetFastElementsCapacityMode set_capacity_mode) { | 8536 SetFastElementsCapacityMode set_capacity_mode) { |
| 8550 Heap* heap = GetHeap(); | 8537 Heap* heap = GetHeap(); |
| 8551 // We should never end in here with a pixel or external array. | 8538 // We should never end in here with a pixel or external array. |
| 8552 ASSERT(!HasExternalArrayElements()); | 8539 ASSERT(!HasExternalArrayElements()); |
| 8553 | 8540 |
| 8554 // Allocate a new fast elements backing store. | 8541 // Allocate a new fast elements backing store. |
| 8555 FixedArray* new_elements = NULL; | 8542 FixedArray* new_elements; |
| 8556 { Object* object; | 8543 { MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); |
| 8557 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); | 8544 if (!maybe->To(&new_elements)) return maybe; |
| 8558 if (!maybe->ToObject(&object)) return maybe; | |
| 8559 new_elements = FixedArray::cast(object); | |
| 8560 } | 8545 } |
| 8561 | 8546 |
| 8562 // Find the new map to use for this object if there is a map change. | 8547 // Find the new map to use for this object if there is a map change. |
| 8563 Map* new_map = NULL; | 8548 Map* new_map = NULL; |
| 8564 if (elements()->map() != heap->non_strict_arguments_elements_map()) { | 8549 if (elements()->map() != heap->non_strict_arguments_elements_map()) { |
| 8565 Object* object; | |
| 8566 // The resized array has FAST_SMI_ONLY_ELEMENTS if the capacity mode forces | 8550 // The resized array has FAST_SMI_ONLY_ELEMENTS if the capacity mode forces |
| 8567 // it, or if it's allowed and the old elements array contained only SMIs. | 8551 // it, or if it's allowed and the old elements array contained only SMIs. |
| 8568 bool has_fast_smi_only_elements = | 8552 bool has_fast_smi_only_elements = |
| 8569 (set_capacity_mode == kForceSmiOnlyElements) || | 8553 (set_capacity_mode == kForceSmiOnlyElements) || |
| 8570 ((set_capacity_mode == kAllowSmiOnlyElements) && | 8554 ((set_capacity_mode == kAllowSmiOnlyElements) && |
| 8571 (elements()->map()->has_fast_smi_only_elements() || | 8555 (elements()->map()->has_fast_smi_only_elements() || |
| 8572 elements() == heap->empty_fixed_array())); | 8556 elements() == heap->empty_fixed_array())); |
| 8573 ElementsKind elements_kind = has_fast_smi_only_elements | 8557 ElementsKind elements_kind = has_fast_smi_only_elements |
| 8574 ? FAST_SMI_ONLY_ELEMENTS | 8558 ? FAST_SMI_ONLY_ELEMENTS |
| 8575 : FAST_ELEMENTS; | 8559 : FAST_ELEMENTS; |
| 8576 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); | 8560 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); |
| 8577 if (!maybe->ToObject(&object)) return maybe; | 8561 if (!maybe->To(&new_map)) return maybe; |
| 8578 new_map = Map::cast(object); | |
| 8579 } | 8562 } |
| 8580 | 8563 |
| 8581 FixedArrayBase* old_elements_raw = elements(); | 8564 FixedArrayBase* old_elements_raw = elements(); |
| 8582 ElementsKind elements_kind = GetElementsKind(); | 8565 ElementsKind elements_kind = GetElementsKind(); |
| 8583 switch (elements_kind) { | 8566 switch (elements_kind) { |
| 8584 case FAST_SMI_ONLY_ELEMENTS: | 8567 case FAST_SMI_ONLY_ELEMENTS: |
| 8585 case FAST_ELEMENTS: { | 8568 case FAST_ELEMENTS: { |
| 8586 AssertNoAllocation no_gc; | 8569 AssertNoAllocation no_gc; |
| 8587 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); | 8570 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); |
| 8588 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), | 8571 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8623 for (uint32_t i = 0; i < old_length; i++) { | 8606 for (uint32_t i = 0; i < old_length; i++) { |
| 8624 if (!old_elements->is_the_hole(i)) { | 8607 if (!old_elements->is_the_hole(i)) { |
| 8625 Object* obj; | 8608 Object* obj; |
| 8626 // Objects must be allocated in the old object space, since the | 8609 // Objects must be allocated in the old object space, since the |
| 8627 // overall number of HeapNumbers needed for the conversion might | 8610 // overall number of HeapNumbers needed for the conversion might |
| 8628 // exceed the capacity of new space, and we would fail repeatedly | 8611 // exceed the capacity of new space, and we would fail repeatedly |
| 8629 // trying to convert the FixedDoubleArray. | 8612 // trying to convert the FixedDoubleArray. |
| 8630 MaybeObject* maybe_value_object = | 8613 MaybeObject* maybe_value_object = |
| 8631 GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i), | 8614 GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i), |
| 8632 TENURED); | 8615 TENURED); |
| 8633 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; | 8616 if (!maybe_value_object->To(&obj)) return maybe_value_object; |
| 8634 // Force write barrier. It's not worth trying to exploit | 8617 // Force write barrier. It's not worth trying to exploit |
| 8635 // elems->GetWriteBarrierMode(), since it requires an | 8618 // elems->GetWriteBarrierMode(), since it requires an |
| 8636 // AssertNoAllocation stack object that would have to be positioned | 8619 // AssertNoAllocation stack object that would have to be positioned |
| 8637 // after the HeapNumber allocation anyway. | 8620 // after the HeapNumber allocation anyway. |
| 8638 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); | 8621 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); |
| 8639 } | 8622 } |
| 8640 } | 8623 } |
| 8641 set_map(new_map); | 8624 set_map(new_map); |
| 8642 set_elements(new_elements); | 8625 set_elements(new_elements); |
| 8643 break; | 8626 break; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8669 } | 8652 } |
| 8670 | 8653 |
| 8671 | 8654 |
| 8672 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 8655 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
| 8673 int capacity, | 8656 int capacity, |
| 8674 int length) { | 8657 int length) { |
| 8675 Heap* heap = GetHeap(); | 8658 Heap* heap = GetHeap(); |
| 8676 // We should never end in here with a pixel or external array. | 8659 // We should never end in here with a pixel or external array. |
| 8677 ASSERT(!HasExternalArrayElements()); | 8660 ASSERT(!HasExternalArrayElements()); |
| 8678 | 8661 |
| 8679 Object* obj; | 8662 FixedDoubleArray* elems; |
| 8680 { MaybeObject* maybe_obj = | 8663 { MaybeObject* maybe_obj = |
| 8681 heap->AllocateUninitializedFixedDoubleArray(capacity); | 8664 heap->AllocateUninitializedFixedDoubleArray(capacity); |
| 8682 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8665 if (!maybe_obj->To(&elems)) return maybe_obj; |
| 8683 } | 8666 } |
| 8684 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); | |
| 8685 | 8667 |
| 8668 Map* new_map; |
| 8686 { MaybeObject* maybe_obj = | 8669 { MaybeObject* maybe_obj = |
| 8687 GetElementsTransitionMap(heap->isolate(), FAST_DOUBLE_ELEMENTS); | 8670 GetElementsTransitionMap(heap->isolate(), FAST_DOUBLE_ELEMENTS); |
| 8688 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8671 if (!maybe_obj->To(&new_map)) return maybe_obj; |
| 8689 } | 8672 } |
| 8690 Map* new_map = Map::cast(obj); | |
| 8691 | 8673 |
| 8692 FixedArrayBase* old_elements = elements(); | 8674 FixedArrayBase* old_elements = elements(); |
| 8693 ElementsKind elements_kind(GetElementsKind()); | 8675 ElementsKind elements_kind(GetElementsKind()); |
| 8694 AssertNoAllocation no_gc; | 8676 AssertNoAllocation no_gc; |
| 8695 if (old_elements->length() != 0) { | 8677 if (old_elements->length() != 0) { |
| 8696 switch (elements_kind) { | 8678 switch (elements_kind) { |
| 8697 case FAST_SMI_ONLY_ELEMENTS: | 8679 case FAST_SMI_ONLY_ELEMENTS: |
| 8698 case FAST_ELEMENTS: { | 8680 case FAST_ELEMENTS: { |
| 8699 elems->Initialize(FixedArray::cast(old_elements)); | 8681 elems->Initialize(FixedArray::cast(old_elements)); |
| 8700 break; | 8682 break; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8732 | 8714 |
| 8733 | 8715 |
| 8734 MaybeObject* JSArray::Initialize(int capacity) { | 8716 MaybeObject* JSArray::Initialize(int capacity) { |
| 8735 Heap* heap = GetHeap(); | 8717 Heap* heap = GetHeap(); |
| 8736 ASSERT(capacity >= 0); | 8718 ASSERT(capacity >= 0); |
| 8737 set_length(Smi::FromInt(0)); | 8719 set_length(Smi::FromInt(0)); |
| 8738 FixedArray* new_elements; | 8720 FixedArray* new_elements; |
| 8739 if (capacity == 0) { | 8721 if (capacity == 0) { |
| 8740 new_elements = heap->empty_fixed_array(); | 8722 new_elements = heap->empty_fixed_array(); |
| 8741 } else { | 8723 } else { |
| 8742 Object* obj; | 8724 MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
| 8743 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); | 8725 if (!maybe_obj->To(&new_elements)) return maybe_obj; |
| 8744 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 8745 } | |
| 8746 new_elements = FixedArray::cast(obj); | |
| 8747 } | 8726 } |
| 8748 set_elements(new_elements); | 8727 set_elements(new_elements); |
| 8749 return this; | 8728 return this; |
| 8750 } | 8729 } |
| 8751 | 8730 |
| 8752 | 8731 |
| 8753 void JSArray::Expand(int required_size) { | 8732 void JSArray::Expand(int required_size) { |
| 8754 GetIsolate()->factory()->SetElementsCapacityAndLength( | 8733 GetIsolate()->factory()->SetElementsCapacityAndLength( |
| 8755 Handle<JSArray>(this), required_size, required_size); | 8734 Handle<JSArray>(this), required_size, required_size); |
| 8756 } | 8735 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8796 | 8775 |
| 8797 int transitions = NumberOfProtoTransitions() + 1; | 8776 int transitions = NumberOfProtoTransitions() + 1; |
| 8798 | 8777 |
| 8799 if (transitions > capacity) { | 8778 if (transitions > capacity) { |
| 8800 if (capacity > kMaxCachedPrototypeTransitions) return this; | 8779 if (capacity > kMaxCachedPrototypeTransitions) return this; |
| 8801 | 8780 |
| 8802 FixedArray* new_cache; | 8781 FixedArray* new_cache; |
| 8803 // Grow array by factor 2 over and above what we need. | 8782 // Grow array by factor 2 over and above what we need. |
| 8804 { MaybeObject* maybe_cache = | 8783 { MaybeObject* maybe_cache = |
| 8805 GetHeap()->AllocateFixedArray(transitions * 2 * step + header); | 8784 GetHeap()->AllocateFixedArray(transitions * 2 * step + header); |
| 8806 if (!maybe_cache->To<FixedArray>(&new_cache)) return maybe_cache; | 8785 if (!maybe_cache->To(&new_cache)) return maybe_cache; |
| 8807 } | 8786 } |
| 8808 | 8787 |
| 8809 for (int i = 0; i < capacity * step; i++) { | 8788 for (int i = 0; i < capacity * step; i++) { |
| 8810 new_cache->set(i + header, cache->get(i + header)); | 8789 new_cache->set(i + header, cache->get(i + header)); |
| 8811 } | 8790 } |
| 8812 cache = new_cache; | 8791 cache = new_cache; |
| 8813 set_prototype_transitions(cache); | 8792 set_prototype_transitions(cache); |
| 8814 } | 8793 } |
| 8815 | 8794 |
| 8816 int last = transitions - 1; | 8795 int last = transitions - 1; |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9299 Object* value, | 9278 Object* value, |
| 9300 StrictModeFlag strict_mode, | 9279 StrictModeFlag strict_mode, |
| 9301 bool check_prototype) { | 9280 bool check_prototype) { |
| 9302 ASSERT(HasFastTypeElements() || | 9281 ASSERT(HasFastTypeElements() || |
| 9303 HasFastArgumentsElements()); | 9282 HasFastArgumentsElements()); |
| 9304 | 9283 |
| 9305 FixedArray* backing_store = FixedArray::cast(elements()); | 9284 FixedArray* backing_store = FixedArray::cast(elements()); |
| 9306 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { | 9285 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 9307 backing_store = FixedArray::cast(backing_store->get(1)); | 9286 backing_store = FixedArray::cast(backing_store->get(1)); |
| 9308 } else { | 9287 } else { |
| 9309 Object* writable; | |
| 9310 MaybeObject* maybe = EnsureWritableFastElements(); | 9288 MaybeObject* maybe = EnsureWritableFastElements(); |
| 9311 if (!maybe->ToObject(&writable)) return maybe; | 9289 if (!maybe->To(&backing_store)) return maybe; |
| 9312 backing_store = FixedArray::cast(writable); | |
| 9313 } | 9290 } |
| 9314 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 9291 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
| 9315 | 9292 |
| 9316 if (check_prototype && | 9293 if (check_prototype && |
| 9317 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 9294 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
| 9318 bool found; | 9295 bool found; |
| 9319 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 9296 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
| 9320 value, | 9297 value, |
| 9321 &found, | 9298 &found, |
| 9322 strict_mode); | 9299 strict_mode); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9355 // Convert to fast double elements if appropriate. | 9332 // Convert to fast double elements if appropriate. |
| 9356 if (HasFastSmiOnlyElements() && !value->IsSmi() && value->IsNumber()) { | 9333 if (HasFastSmiOnlyElements() && !value->IsSmi() && value->IsNumber()) { |
| 9357 MaybeObject* maybe = | 9334 MaybeObject* maybe = |
| 9358 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 9335 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); |
| 9359 if (maybe->IsFailure()) return maybe; | 9336 if (maybe->IsFailure()) return maybe; |
| 9360 FixedDoubleArray::cast(elements())->set(index, value->Number()); | 9337 FixedDoubleArray::cast(elements())->set(index, value->Number()); |
| 9361 return value; | 9338 return value; |
| 9362 } | 9339 } |
| 9363 // Change elements kind from SMI_ONLY to generic FAST if necessary. | 9340 // Change elements kind from SMI_ONLY to generic FAST if necessary. |
| 9364 if (HasFastSmiOnlyElements() && !value->IsSmi()) { | 9341 if (HasFastSmiOnlyElements() && !value->IsSmi()) { |
| 9365 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | |
| 9366 FAST_ELEMENTS); | |
| 9367 Map* new_map; | 9342 Map* new_map; |
| 9368 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; | 9343 { MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), |
| 9344 FAST_ELEMENTS); |
| 9345 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 9346 } |
| 9369 set_map(new_map); | 9347 set_map(new_map); |
| 9370 if (FLAG_trace_elements_transitions) { | 9348 if (FLAG_trace_elements_transitions) { |
| 9371 PrintElementsTransition(stdout, FAST_SMI_ONLY_ELEMENTS, elements(), | 9349 PrintElementsTransition(stdout, FAST_SMI_ONLY_ELEMENTS, elements(), |
| 9372 FAST_ELEMENTS, elements()); | 9350 FAST_ELEMENTS, elements()); |
| 9373 } | 9351 } |
| 9374 } | 9352 } |
| 9375 // Increase backing store capacity if that's been decided previously. | 9353 // Increase backing store capacity if that's been decided previously. |
| 9376 if (new_capacity != capacity) { | 9354 if (new_capacity != capacity) { |
| 9377 Object* new_elements; | 9355 FixedArray* new_elements; |
| 9378 SetFastElementsCapacityMode set_capacity_mode = | 9356 SetFastElementsCapacityMode set_capacity_mode = |
| 9379 value->IsSmi() && HasFastSmiOnlyElements() | 9357 value->IsSmi() && HasFastSmiOnlyElements() |
| 9380 ? kAllowSmiOnlyElements | 9358 ? kAllowSmiOnlyElements |
| 9381 : kDontAllowSmiOnlyElements; | 9359 : kDontAllowSmiOnlyElements; |
| 9382 MaybeObject* maybe = | 9360 { MaybeObject* maybe = |
| 9383 SetFastElementsCapacityAndLength(new_capacity, | 9361 SetFastElementsCapacityAndLength(new_capacity, |
| 9384 array_length, | 9362 array_length, |
| 9385 set_capacity_mode); | 9363 set_capacity_mode); |
| 9386 if (!maybe->ToObject(&new_elements)) return maybe; | 9364 if (!maybe->To(&new_elements)) return maybe; |
| 9387 FixedArray::cast(new_elements)->set(index, value); | 9365 } |
| 9366 new_elements->set(index, value); |
| 9388 return value; | 9367 return value; |
| 9389 } | 9368 } |
| 9390 // Finally, set the new element and length. | 9369 // Finally, set the new element and length. |
| 9391 ASSERT(elements()->IsFixedArray()); | 9370 ASSERT(elements()->IsFixedArray()); |
| 9392 backing_store->set(index, value); | 9371 backing_store->set(index, value); |
| 9393 if (must_update_array_length) { | 9372 if (must_update_array_length) { |
| 9394 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); | 9373 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); |
| 9395 } | 9374 } |
| 9396 return value; | 9375 return value; |
| 9397 } | 9376 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9477 Handle<Object> args[1] = { name }; | 9456 Handle<Object> args[1] = { name }; |
| 9478 Handle<Object> error = | 9457 Handle<Object> error = |
| 9479 isolate->factory()->NewTypeError("object_not_extensible", | 9458 isolate->factory()->NewTypeError("object_not_extensible", |
| 9480 HandleVector(args, 1)); | 9459 HandleVector(args, 1)); |
| 9481 return isolate->Throw(*error); | 9460 return isolate->Throw(*error); |
| 9482 } | 9461 } |
| 9483 } | 9462 } |
| 9484 FixedArrayBase* new_dictionary; | 9463 FixedArrayBase* new_dictionary; |
| 9485 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 9464 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 9486 MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); | 9465 MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); |
| 9487 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; | 9466 if (!maybe->To(&new_dictionary)) return maybe; |
| 9488 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { | 9467 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { |
| 9489 if (is_arguments) { | 9468 if (is_arguments) { |
| 9490 elements->set(1, new_dictionary); | 9469 elements->set(1, new_dictionary); |
| 9491 } else { | 9470 } else { |
| 9492 set_elements(new_dictionary); | 9471 set_elements(new_dictionary); |
| 9493 } | 9472 } |
| 9494 dictionary = SeededNumberDictionary::cast(new_dictionary); | 9473 dictionary = SeededNumberDictionary::cast(new_dictionary); |
| 9495 } | 9474 } |
| 9496 } | 9475 } |
| 9497 | 9476 |
| (...skipping 3526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13024 if (break_point_objects()->IsUndefined()) return 0; | 13003 if (break_point_objects()->IsUndefined()) return 0; |
| 13025 // Single break point. | 13004 // Single break point. |
| 13026 if (!break_point_objects()->IsFixedArray()) return 1; | 13005 if (!break_point_objects()->IsFixedArray()) return 1; |
| 13027 // Multiple break points. | 13006 // Multiple break points. |
| 13028 return FixedArray::cast(break_point_objects())->length(); | 13007 return FixedArray::cast(break_point_objects())->length(); |
| 13029 } | 13008 } |
| 13030 #endif // ENABLE_DEBUGGER_SUPPORT | 13009 #endif // ENABLE_DEBUGGER_SUPPORT |
| 13031 | 13010 |
| 13032 | 13011 |
| 13033 } } // namespace v8::internal | 13012 } } // namespace v8::internal |
| OLD | NEW |