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 3530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3541 } | 3541 } |
3542 | 3542 |
3543 | 3543 |
3544 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3544 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
3545 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3545 ASSERT(value->IsNull() || value->IsJSReceiver()); |
3546 WRITE_FIELD(this, kPrototypeOffset, value); | 3546 WRITE_FIELD(this, kPrototypeOffset, value); |
3547 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); | 3547 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
3548 } | 3548 } |
3549 | 3549 |
3550 | 3550 |
3551 DescriptorArray* Map::instance_descriptors() { | |
3552 if (HasTransitionArray()) return transitions()->descriptors(); | |
3553 Object* back_pointer = GetBackPointer(); | |
3554 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); | |
3555 return Map::cast(back_pointer)->instance_descriptors(); | |
3556 } | |
3557 | |
3558 | |
3559 enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY }; | |
3560 | |
3561 | |
3562 // If the descriptor is using the empty transition array, install a new empty | 3551 // If the descriptor is using the empty transition array, install a new empty |
3563 // transition array that will have place for an element transition. | 3552 // transition array that will have place for an element transition. |
3564 static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) { | 3553 static MaybeObject* EnsureHasTransitionArray(Map* map) { |
3565 TransitionArray* transitions; | 3554 TransitionArray* transitions; |
3566 MaybeObject* maybe_transitions; | 3555 MaybeObject* maybe_transitions; |
3567 if (!map->HasTransitionArray()) { | 3556 if (!map->HasTransitionArray()) { |
3568 if (kind == FULL_TRANSITION_ARRAY) { | 3557 maybe_transitions = TransitionArray::Allocate(0); |
3569 maybe_transitions = TransitionArray::Allocate(0); | |
3570 } else { | |
3571 maybe_transitions = TransitionArray::AllocateDescriptorsHolder(); | |
3572 } | |
3573 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 3558 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
3574 transitions->set_back_pointer_storage(map->GetBackPointer()); | 3559 transitions->set_back_pointer_storage(map->GetBackPointer()); |
3575 } else if (kind == FULL_TRANSITION_ARRAY && | 3560 } else if (!map->transitions()->IsFullTransitionArray()) { |
3576 !map->transitions()->IsFullTransitionArray()) { | |
3577 maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); | 3561 maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); |
3578 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 3562 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
3579 } else { | 3563 } else { |
3580 return map; | 3564 return map; |
3581 } | 3565 } |
3582 map->set_transitions(transitions); | 3566 map->set_transitions(transitions); |
3583 return transitions; | 3567 return transitions; |
3584 } | 3568 } |
3585 | 3569 |
3586 | 3570 |
3587 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { | 3571 void Map::InitializeDescriptors(DescriptorArray* descriptors) { |
3588 ASSERT(!is_shared()); | |
3589 MaybeObject* maybe_failure = | |
3590 EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER); | |
3591 if (maybe_failure->IsFailure()) return maybe_failure; | |
3592 | |
3593 ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors()); | |
3594 transitions()->set_descriptors(value); | |
3595 return this; | |
3596 } | |
3597 | |
3598 | |
3599 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { | |
3600 int len = descriptors->number_of_descriptors(); | 3572 int len = descriptors->number_of_descriptors(); |
3601 #ifdef DEBUG | 3573 #ifdef DEBUG |
3602 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); | 3574 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); |
3603 | 3575 |
3604 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; | 3576 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; |
3605 for (int i = 0; i < len; ++i) used_indices[i] = false; | 3577 for (int i = 0; i < len; ++i) used_indices[i] = false; |
3606 | 3578 |
3607 // Ensure that all enumeration indexes between 1 and length occur uniquely in | 3579 // Ensure that all enumeration indexes between 1 and length occur uniquely in |
3608 // the descriptor array. | 3580 // the descriptor array. |
3609 for (int i = 0; i < len; ++i) { | 3581 for (int i = 0; i < len; ++i) { |
3610 int enum_index = descriptors->GetDetails(i).descriptor_index() - | 3582 int enum_index = descriptors->GetDetails(i).descriptor_index() - |
3611 PropertyDetails::kInitialIndex; | 3583 PropertyDetails::kInitialIndex; |
3612 ASSERT(0 <= enum_index && enum_index < len); | 3584 ASSERT(0 <= enum_index && enum_index < len); |
3613 ASSERT(!used_indices[enum_index]); | 3585 ASSERT(!used_indices[enum_index]); |
3614 used_indices[enum_index] = true; | 3586 used_indices[enum_index] = true; |
3615 } | 3587 } |
3616 #endif | 3588 #endif |
3617 | 3589 |
3618 MaybeObject* maybe_failure = SetDescriptors(descriptors); | 3590 set_instance_descriptors(descriptors); |
3619 if (maybe_failure->IsFailure()) return maybe_failure; | |
3620 | |
3621 SetNumberOfOwnDescriptors(len); | 3591 SetNumberOfOwnDescriptors(len); |
3622 return this; | |
3623 } | 3592 } |
3624 | 3593 |
3625 | 3594 |
| 3595 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset) |
3626 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) | 3596 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) |
3627 | 3597 |
3628 | 3598 |
3629 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { | 3599 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { |
3630 Object* back_pointer = GetBackPointer(); | 3600 Object* back_pointer = GetBackPointer(); |
3631 | 3601 |
3632 if (Heap::ShouldZapGarbage() && HasTransitionArray()) { | 3602 if (Heap::ShouldZapGarbage() && HasTransitionArray()) { |
3633 ZapTransitions(); | 3603 ZapTransitions(); |
3634 } | 3604 } |
3635 | 3605 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3681 return FixedArray::SizeFor(transitions()->length() + | 3651 return FixedArray::SizeFor(transitions()->length() + |
3682 TransitionArray::kTransitionSize) | 3652 TransitionArray::kTransitionSize) |
3683 <= Page::kMaxNonCodeHeapObjectSize; | 3653 <= Page::kMaxNonCodeHeapObjectSize; |
3684 } | 3654 } |
3685 | 3655 |
3686 | 3656 |
3687 MaybeObject* Map::AddTransition(String* key, | 3657 MaybeObject* Map::AddTransition(String* key, |
3688 Map* target, | 3658 Map* target, |
3689 SimpleTransitionFlag flag) { | 3659 SimpleTransitionFlag flag) { |
3690 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); | 3660 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); |
3691 return TransitionArray::NewWith( | 3661 return TransitionArray::NewWith(flag, key, target, GetBackPointer()); |
3692 flag, key, target, instance_descriptors(), GetBackPointer()); | |
3693 } | 3662 } |
3694 | 3663 |
3695 | 3664 |
3696 void Map::SetTransition(int transition_index, Map* target) { | 3665 void Map::SetTransition(int transition_index, Map* target) { |
3697 transitions()->SetTarget(transition_index, target); | 3666 transitions()->SetTarget(transition_index, target); |
3698 } | 3667 } |
3699 | 3668 |
3700 | 3669 |
3701 Map* Map::GetTransition(int transition_index) { | 3670 Map* Map::GetTransition(int transition_index) { |
3702 return transitions()->GetTarget(transition_index); | 3671 return transitions()->GetTarget(transition_index); |
3703 } | 3672 } |
3704 | 3673 |
3705 | 3674 |
3706 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { | 3675 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { |
3707 DescriptorArray* descriptors = instance_descriptors(); | 3676 MaybeObject* allow_elements = EnsureHasTransitionArray(this); |
3708 MaybeObject* allow_elements = | |
3709 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | |
3710 if (allow_elements->IsFailure()) return allow_elements; | 3677 if (allow_elements->IsFailure()) return allow_elements; |
3711 transitions()->set_descriptors(descriptors); | |
3712 transitions()->set_elements_transition(transitioned_map); | 3678 transitions()->set_elements_transition(transitioned_map); |
3713 return this; | 3679 return this; |
3714 } | 3680 } |
3715 | 3681 |
3716 | 3682 |
3717 FixedArray* Map::GetPrototypeTransitions() { | 3683 FixedArray* Map::GetPrototypeTransitions() { |
3718 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); | 3684 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); |
3719 if (!transitions()->HasPrototypeTransitions()) { | 3685 if (!transitions()->HasPrototypeTransitions()) { |
3720 return GetHeap()->empty_fixed_array(); | 3686 return GetHeap()->empty_fixed_array(); |
3721 } | 3687 } |
3722 return transitions()->GetPrototypeTransitions(); | 3688 return transitions()->GetPrototypeTransitions(); |
3723 } | 3689 } |
3724 | 3690 |
3725 | 3691 |
3726 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { | 3692 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { |
3727 DescriptorArray* descriptors = instance_descriptors(); | 3693 MaybeObject* allow_prototype = EnsureHasTransitionArray(this); |
3728 MaybeObject* allow_prototype = | |
3729 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY); | |
3730 if (allow_prototype->IsFailure()) return allow_prototype; | 3694 if (allow_prototype->IsFailure()) return allow_prototype; |
3731 #ifdef DEBUG | 3695 #ifdef DEBUG |
3732 if (HasPrototypeTransitions()) { | 3696 if (HasPrototypeTransitions()) { |
3733 ASSERT(GetPrototypeTransitions() != proto_transitions); | 3697 ASSERT(GetPrototypeTransitions() != proto_transitions); |
3734 ZapPrototypeTransitions(); | 3698 ZapPrototypeTransitions(); |
3735 } | 3699 } |
3736 #endif | 3700 #endif |
3737 transitions()->set_descriptors(descriptors); | |
3738 transitions()->SetPrototypeTransitions(proto_transitions); | 3701 transitions()->SetPrototypeTransitions(proto_transitions); |
3739 return this; | 3702 return this; |
3740 } | 3703 } |
3741 | 3704 |
3742 | 3705 |
3743 bool Map::HasPrototypeTransitions() { | 3706 bool Map::HasPrototypeTransitions() { |
3744 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); | 3707 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); |
3745 } | 3708 } |
3746 | 3709 |
3747 | 3710 |
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5540 #undef WRITE_UINT32_FIELD | 5503 #undef WRITE_UINT32_FIELD |
5541 #undef READ_SHORT_FIELD | 5504 #undef READ_SHORT_FIELD |
5542 #undef WRITE_SHORT_FIELD | 5505 #undef WRITE_SHORT_FIELD |
5543 #undef READ_BYTE_FIELD | 5506 #undef READ_BYTE_FIELD |
5544 #undef WRITE_BYTE_FIELD | 5507 #undef WRITE_BYTE_FIELD |
5545 | 5508 |
5546 | 5509 |
5547 } } // namespace v8::internal | 5510 } } // namespace v8::internal |
5548 | 5511 |
5549 #endif // V8_OBJECTS_INL_H_ | 5512 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |