| Index: src/objects-inl.h
|
| diff --git a/src/objects-inl.h b/src/objects-inl.h
|
| index 3c34be5119f65c385a07df0544f57f5856f0a58f..c39167ef7050b9ab812cc73abd7fe67f581ffe3a 100644
|
| --- a/src/objects-inl.h
|
| +++ b/src/objects-inl.h
|
| @@ -3489,12 +3489,7 @@ void Map::set_bit_field3(int value) {
|
|
|
|
|
| Object* Map::GetBackPointer() {
|
| - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
|
| - if (object->IsFixedArray()) {
|
| - return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
|
| - } else {
|
| - return object;
|
| - }
|
| + return READ_FIELD(this, kBackPointerOffset);
|
| }
|
|
|
|
|
| @@ -3532,9 +3527,9 @@ static MaybeObject* AllowTransitions(Map* map) {
|
| }
|
|
|
|
|
| -// If the descriptor does not have a transition array, install a new
|
| -// transition array that has room for an element transition.
|
| -static MaybeObject* AllowElementsTransition(Map* map) {
|
| +// If the descriptor is using the empty transition array, install a new empty
|
| +// transition array that will have place for an element transition.
|
| +static MaybeObject* EnsureHasTransitionArray(Map* map) {
|
| if (map->HasTransitionArray()) return map;
|
|
|
| AllowTransitions(map);
|
| @@ -3549,13 +3544,41 @@ static MaybeObject* AllowElementsTransition(Map* map) {
|
|
|
|
|
| MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
|
| - MaybeObject* allow_elements = AllowElementsTransition(this);
|
| + MaybeObject* allow_elements = EnsureHasTransitionArray(this);
|
| if (allow_elements->IsFailure()) return allow_elements;
|
| transitions()->set_elements_transition(transitioned_map);
|
| return this;
|
| }
|
|
|
|
|
| +FixedArray* Map::GetPrototypeTransitions() {
|
| + if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
|
| + if (!transitions()->HasPrototypeTransitions()) {
|
| + return GetHeap()->empty_fixed_array();
|
| + }
|
| + return transitions()->GetPrototypeTransitions();
|
| +}
|
| +
|
| +
|
| +MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
|
| + MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
|
| + if (allow_prototype->IsFailure()) return allow_prototype;
|
| +#ifdef DEBUG
|
| + if (HasPrototypeTransitions()) {
|
| + ASSERT(GetPrototypeTransitions() != proto_transitions);
|
| + ZapPrototypeTransitions();
|
| + }
|
| +#endif
|
| + transitions()->SetPrototypeTransitions(proto_transitions);
|
| + return this;
|
| +}
|
| +
|
| +
|
| +bool Map::HasPrototypeTransitions() {
|
| + return HasTransitionArray() && transitions()->HasPrototypeTransitions();
|
| +}
|
| +
|
| +
|
| TransitionArray* Map::transitions() {
|
| return instance_descriptors()->transitions();
|
| }
|
| @@ -3588,57 +3611,38 @@ MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
|
| }
|
|
|
|
|
| +void Map::init_back_pointer(Object* undefined) {
|
| + ASSERT(undefined->IsUndefined());
|
| + WRITE_FIELD(this, kBackPointerOffset, undefined);
|
| +}
|
| +
|
| +
|
| void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
|
| Heap* heap = GetHeap();
|
| ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
|
| ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
|
| (value->IsMap() && GetBackPointer()->IsUndefined()));
|
| - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
|
| - if (object->IsFixedArray()) {
|
| - FixedArray::cast(object)->set(
|
| - kProtoTransitionBackPointerOffset, value, mode);
|
| - } else {
|
| - WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
|
| - CONDITIONAL_WRITE_BARRIER(
|
| - heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
|
| - }
|
| -}
|
| -
|
| -
|
| -FixedArray* Map::prototype_transitions() {
|
| - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
|
| - if (object->IsFixedArray()) {
|
| - return FixedArray::cast(object);
|
| - } else {
|
| - return GetHeap()->empty_fixed_array();
|
| - }
|
| + WRITE_FIELD(this, kBackPointerOffset, value);
|
| + CONDITIONAL_WRITE_BARRIER(heap, this, kBackPointerOffset, value, mode);
|
| }
|
|
|
|
|
| -void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
|
| - Heap* heap = GetHeap();
|
| - ASSERT(value != heap->empty_fixed_array());
|
| - value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
|
| -#ifdef DEBUG
|
| - if (value != prototype_transitions()) {
|
| - ZapPrototypeTransitions();
|
| - }
|
| -#endif
|
| - WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
|
| - CONDITIONAL_WRITE_BARRIER(
|
| - heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
|
| -}
|
| -
|
| -
|
| -void Map::init_prototype_transitions(Object* undefined) {
|
| - ASSERT(undefined->IsUndefined());
|
| - WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
|
| +// Can either be Smi (no transitions), normal transition array, or a transition
|
| +// array with the header overwritten as a Smi (thus iterating).
|
| +TransitionArray* Map::unchecked_transition_array() {
|
| + ASSERT(HasTransitionArray());
|
| + Object* object = *HeapObject::RawField(instance_descriptors(),
|
| + DescriptorArray::kTransitionsOffset);
|
| + ASSERT(!object->IsSmi());
|
| + TransitionArray* transition_array = static_cast<TransitionArray*>(object);
|
| + return transition_array;
|
| }
|
|
|
|
|
| -HeapObject* Map::unchecked_prototype_transitions() {
|
| - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
|
| - return reinterpret_cast<HeapObject*>(object);
|
| +HeapObject* Map::UncheckedPrototypeTransitions() {
|
| + ASSERT(HasTransitionArray());
|
| + ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
|
| + return unchecked_transition_array()->UncheckedPrototypeTransitions();
|
| }
|
|
|
|
|
|
|