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 |