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 2147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2158 ASSERT(desc->GetDetails().descriptor_index() <= | 2158 ASSERT(desc->GetDetails().descriptor_index() <= |
2159 number_of_descriptors()); | 2159 number_of_descriptors()); |
2160 ASSERT(desc->GetDetails().descriptor_index() > 0); | 2160 ASSERT(desc->GetDetails().descriptor_index() > 0); |
2161 | 2161 |
2162 set(ToKeyIndex(descriptor_number), desc->GetKey()); | 2162 set(ToKeyIndex(descriptor_number), desc->GetKey()); |
2163 set(ToValueIndex(descriptor_number), desc->GetValue()); | 2163 set(ToValueIndex(descriptor_number), desc->GetValue()); |
2164 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); | 2164 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); |
2165 } | 2165 } |
2166 | 2166 |
2167 | 2167 |
2168 void DescriptorArray::EraseDescriptor(Heap* heap, int descriptor_number) { | |
2169 set_null_unchecked(heap, ToKeyIndex(descriptor_number)); | |
2170 set_null_unchecked(heap, ToValueIndex(descriptor_number)); | |
2171 } | |
2172 | |
2173 | |
2174 void DescriptorArray::Append(Descriptor* desc, | 2168 void DescriptorArray::Append(Descriptor* desc, |
2175 const WhitenessWitness& witness) { | 2169 const WhitenessWitness& witness) { |
2176 int descriptor_number = number_of_descriptors(); | 2170 int descriptor_number = number_of_descriptors(); |
2177 int enumeration_index = descriptor_number + 1; | 2171 int enumeration_index = descriptor_number + 1; |
2178 SetNumberOfDescriptors(descriptor_number + 1); | 2172 SetNumberOfDescriptors(descriptor_number + 1); |
2179 desc->SetEnumerationIndex(enumeration_index); | 2173 desc->SetEnumerationIndex(enumeration_index); |
2180 Set(descriptor_number, desc, witness); | 2174 Set(descriptor_number, desc, witness); |
2181 | 2175 |
2182 uint32_t hash = desc->GetKey()->Hash(); | 2176 uint32_t hash = desc->GetKey()->Hash(); |
2183 | 2177 |
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3547 } | 3541 } |
3548 | 3542 |
3549 | 3543 |
3550 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3544 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
3551 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3545 ASSERT(value->IsNull() || value->IsJSReceiver()); |
3552 WRITE_FIELD(this, kPrototypeOffset, value); | 3546 WRITE_FIELD(this, kPrototypeOffset, value); |
3553 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); | 3547 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
3554 } | 3548 } |
3555 | 3549 |
3556 | 3550 |
3557 JSGlobalPropertyCell* Map::descriptors_pointer() { | |
3558 ASSERT(HasTransitionArray()); | |
3559 return transitions()->descriptors_pointer(); | |
3560 } | |
3561 | |
3562 | |
3563 DescriptorArray* Map::instance_descriptors() { | 3551 DescriptorArray* Map::instance_descriptors() { |
3564 if (HasTransitionArray()) return transitions()->descriptors(); | 3552 if (HasTransitionArray()) return transitions()->descriptors(); |
3565 Object* back_pointer = GetBackPointer(); | 3553 Object* back_pointer = GetBackPointer(); |
3566 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); | 3554 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); |
3567 return Map::cast(back_pointer)->instance_descriptors(); | 3555 return Map::cast(back_pointer)->instance_descriptors(); |
3568 } | 3556 } |
3569 | 3557 |
3570 | 3558 |
3571 enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY }; | 3559 enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY }; |
3572 | 3560 |
3573 | 3561 |
3574 // If the descriptor is using the empty transition array, install a new empty | 3562 // If the descriptor is using the empty transition array, install a new empty |
3575 // transition array that will have place for an element transition. | 3563 // transition array that will have place for an element transition. |
3576 static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) { | 3564 static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) { |
3577 TransitionArray* transitions; | 3565 TransitionArray* transitions; |
3578 MaybeObject* maybe_transitions; | 3566 MaybeObject* maybe_transitions; |
3579 if (map->HasTransitionArray()) { | 3567 if (!map->HasTransitionArray()) { |
3580 if (kind != FULL_TRANSITION_ARRAY || | 3568 if (kind == FULL_TRANSITION_ARRAY) { |
3581 map->transitions()->IsFullTransitionArray()) { | 3569 maybe_transitions = TransitionArray::Allocate(0); |
3582 return map; | 3570 } else { |
| 3571 maybe_transitions = TransitionArray::AllocateDescriptorsHolder(); |
3583 } | 3572 } |
| 3573 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| 3574 transitions->set_back_pointer_storage(map->GetBackPointer()); |
| 3575 } else if (kind == FULL_TRANSITION_ARRAY && |
| 3576 !map->transitions()->IsFullTransitionArray()) { |
3584 maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); | 3577 maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); |
3585 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 3578 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
3586 } else { | 3579 } else { |
3587 JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer(); | 3580 return map; |
3588 if (kind == FULL_TRANSITION_ARRAY) { | |
3589 maybe_transitions = TransitionArray::Allocate(0, pointer); | |
3590 } else { | |
3591 maybe_transitions = TransitionArray::AllocateDescriptorsHolder(pointer); | |
3592 } | |
3593 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
3594 transitions->set_back_pointer_storage(map->GetBackPointer()); | |
3595 } | 3581 } |
3596 map->set_transitions(transitions); | 3582 map->set_transitions(transitions); |
3597 return transitions; | 3583 return transitions; |
3598 } | 3584 } |
3599 | 3585 |
3600 | 3586 |
3601 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { | 3587 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { |
3602 ASSERT(!is_shared()); | 3588 ASSERT(!is_shared()); |
3603 MaybeObject* maybe_failure = | 3589 MaybeObject* maybe_failure = |
3604 EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER); | 3590 EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3694 | 3680 |
3695 | 3681 |
3696 bool Map::CanHaveMoreTransitions() { | 3682 bool Map::CanHaveMoreTransitions() { |
3697 if (!HasTransitionArray()) return true; | 3683 if (!HasTransitionArray()) return true; |
3698 return FixedArray::SizeFor(transitions()->length() + | 3684 return FixedArray::SizeFor(transitions()->length() + |
3699 TransitionArray::kTransitionSize) | 3685 TransitionArray::kTransitionSize) |
3700 <= Page::kMaxNonCodeHeapObjectSize; | 3686 <= Page::kMaxNonCodeHeapObjectSize; |
3701 } | 3687 } |
3702 | 3688 |
3703 | 3689 |
3704 JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() { | |
3705 if (!owns_descriptors()) return NULL; | |
3706 Object* back_pointer = GetBackPointer(); | |
3707 if (back_pointer->IsUndefined()) return NULL; | |
3708 Map* map = Map::cast(back_pointer); | |
3709 ASSERT(map->HasTransitionArray()); | |
3710 return map->transitions()->descriptors_pointer(); | |
3711 } | |
3712 | |
3713 | |
3714 MaybeObject* Map::AddTransition(String* key, | 3690 MaybeObject* Map::AddTransition(String* key, |
3715 Map* target, | 3691 Map* target, |
3716 SimpleTransitionFlag flag) { | 3692 SimpleTransitionFlag flag) { |
3717 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); | 3693 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); |
3718 JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer(); | |
3719 return TransitionArray::NewWith( | 3694 return TransitionArray::NewWith( |
3720 flag, key, target, descriptors_pointer, GetBackPointer()); | 3695 flag, key, target, instance_descriptors(), GetBackPointer()); |
3721 } | 3696 } |
3722 | 3697 |
3723 | 3698 |
3724 void Map::SetTransition(int transition_index, Map* target) { | 3699 void Map::SetTransition(int transition_index, Map* target) { |
3725 transitions()->SetTarget(transition_index, target); | 3700 transitions()->SetTarget(transition_index, target); |
3726 } | 3701 } |
3727 | 3702 |
3728 | 3703 |
3729 Map* Map::GetTransition(int transition_index) { | 3704 Map* Map::GetTransition(int transition_index) { |
3730 return transitions()->GetTarget(transition_index); | 3705 return transitions()->GetTarget(transition_index); |
3731 } | 3706 } |
3732 | 3707 |
3733 | 3708 |
3734 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { | 3709 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { |
| 3710 DescriptorArray* descriptors = instance_descriptors(); |
3735 MaybeObject* allow_elements = | 3711 MaybeObject* allow_elements = |
3736 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | 3712 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); |
3737 if (allow_elements->IsFailure()) return allow_elements; | 3713 if (allow_elements->IsFailure()) return allow_elements; |
| 3714 transitions()->set_descriptors(descriptors); |
3738 transitions()->set_elements_transition(transitioned_map); | 3715 transitions()->set_elements_transition(transitioned_map); |
3739 return this; | 3716 return this; |
3740 } | 3717 } |
3741 | 3718 |
3742 | 3719 |
3743 FixedArray* Map::GetPrototypeTransitions() { | 3720 FixedArray* Map::GetPrototypeTransitions() { |
3744 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); | 3721 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); |
3745 if (!transitions()->HasPrototypeTransitions()) { | 3722 if (!transitions()->HasPrototypeTransitions()) { |
3746 return GetHeap()->empty_fixed_array(); | 3723 return GetHeap()->empty_fixed_array(); |
3747 } | 3724 } |
3748 return transitions()->GetPrototypeTransitions(); | 3725 return transitions()->GetPrototypeTransitions(); |
3749 } | 3726 } |
3750 | 3727 |
3751 | 3728 |
3752 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { | 3729 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { |
| 3730 DescriptorArray* descriptors = instance_descriptors(); |
3753 MaybeObject* allow_prototype = | 3731 MaybeObject* allow_prototype = |
3754 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | 3732 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); |
3755 if (allow_prototype->IsFailure()) return allow_prototype; | 3733 if (allow_prototype->IsFailure()) return allow_prototype; |
3756 #ifdef DEBUG | 3734 #ifdef DEBUG |
3757 if (HasPrototypeTransitions()) { | 3735 if (HasPrototypeTransitions()) { |
3758 ASSERT(GetPrototypeTransitions() != proto_transitions); | 3736 ASSERT(GetPrototypeTransitions() != proto_transitions); |
3759 ZapPrototypeTransitions(); | 3737 ZapPrototypeTransitions(); |
3760 } | 3738 } |
3761 #endif | 3739 #endif |
| 3740 transitions()->set_descriptors(descriptors); |
3762 transitions()->SetPrototypeTransitions(proto_transitions); | 3741 transitions()->SetPrototypeTransitions(proto_transitions); |
3763 return this; | 3742 return this; |
3764 } | 3743 } |
3765 | 3744 |
3766 | 3745 |
3767 bool Map::HasPrototypeTransitions() { | 3746 bool Map::HasPrototypeTransitions() { |
3768 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); | 3747 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); |
3769 } | 3748 } |
3770 | 3749 |
3771 | 3750 |
(...skipping 1793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5565 #undef WRITE_UINT32_FIELD | 5544 #undef WRITE_UINT32_FIELD |
5566 #undef READ_SHORT_FIELD | 5545 #undef READ_SHORT_FIELD |
5567 #undef WRITE_SHORT_FIELD | 5546 #undef WRITE_SHORT_FIELD |
5568 #undef READ_BYTE_FIELD | 5547 #undef READ_BYTE_FIELD |
5569 #undef WRITE_BYTE_FIELD | 5548 #undef WRITE_BYTE_FIELD |
5570 | 5549 |
5571 | 5550 |
5572 } } // namespace v8::internal | 5551 } } // namespace v8::internal |
5573 | 5552 |
5574 #endif // V8_OBJECTS_INL_H_ | 5553 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |