Index: src/transitions-inl.h |
diff --git a/src/transitions-inl.h b/src/transitions-inl.h |
index f31eff96ba19e6e8e1dca0f1a4b3ee0c7c654a53..fd8eb8b0b652a463365591b3a0b7a9f00e3bb9a4 100644 |
--- a/src/transitions-inl.h |
+++ b/src/transitions-inl.h |
@@ -11,19 +11,55 @@ |
namespace internal { |
+#define FIELD_ADDR(p, offset) \ |
+ (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) |
+ |
+#define WRITE_FIELD(p, offset, value) \ |
+ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) |
+ |
+#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \ |
+ if (mode == UPDATE_WRITE_BARRIER) { \ |
+ heap->incremental_marking()->RecordWrite( \ |
+ object, HeapObject::RawField(object, offset), value); \ |
+ if (heap->InNewSpace(value)) { \ |
+ heap->RecordWrite(object->address(), offset); \ |
+ } \ |
+ } |
+ |
+ |
TransitionArray* TransitionArray::cast(Object* object) { |
DCHECK(object->IsTransitionArray()); |
return reinterpret_cast<TransitionArray*>(object); |
} |
+bool TransitionArray::HasElementsTransition() { |
+ return SearchSpecial(GetHeap()->elements_transition_symbol()) != kNotFound; |
+} |
+ |
+ |
+Object* TransitionArray::back_pointer_storage() { |
+ return get(kBackPointerStorageIndex); |
+} |
+ |
+ |
+void TransitionArray::set_back_pointer_storage(Object* back_pointer, |
+ WriteBarrierMode mode) { |
+ Heap* heap = GetHeap(); |
+ WRITE_FIELD(this, kBackPointerStorageOffset, back_pointer); |
+ CONDITIONAL_WRITE_BARRIER( |
+ heap, this, kBackPointerStorageOffset, back_pointer, mode); |
+} |
+ |
+ |
bool TransitionArray::HasPrototypeTransitions() { |
- return get(kPrototypeTransitionsIndex) != Smi::FromInt(0); |
+ return IsFullTransitionArray() && |
+ get(kPrototypeTransitionsIndex) != Smi::FromInt(0); |
} |
FixedArray* TransitionArray::GetPrototypeTransitions() { |
- DCHECK(HasPrototypeTransitions()); // Callers must check first. |
+ DCHECK(IsFullTransitionArray()); |
Object* prototype_transitions = get(kPrototypeTransitionsIndex); |
return FixedArray::cast(prototype_transitions); |
} |
@@ -31,68 +67,88 @@ |
void TransitionArray::SetPrototypeTransitions(FixedArray* transitions, |
WriteBarrierMode mode) { |
+ DCHECK(IsFullTransitionArray()); |
DCHECK(transitions->IsFixedArray()); |
- set(kPrototypeTransitionsIndex, transitions, mode); |
+ Heap* heap = GetHeap(); |
+ WRITE_FIELD(this, kPrototypeTransitionsOffset, transitions); |
+ CONDITIONAL_WRITE_BARRIER( |
+ heap, this, kPrototypeTransitionsOffset, transitions, mode); |
} |
Object** TransitionArray::GetPrototypeTransitionsSlot() { |
- return RawFieldOfElementAt(kPrototypeTransitionsIndex); |
+ return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
+ kPrototypeTransitionsOffset); |
} |
Object** TransitionArray::GetKeySlot(int transition_number) { |
+ DCHECK(!IsSimpleTransition()); |
DCHECK(transition_number < number_of_transitions()); |
return RawFieldOfElementAt(ToKeyIndex(transition_number)); |
} |
Name* TransitionArray::GetKey(int transition_number) { |
+ if (IsSimpleTransition()) { |
+ Map* target = GetTarget(kSimpleTransitionIndex); |
+ int descriptor = target->LastAdded(); |
+ Name* key = target->instance_descriptors()->GetKey(descriptor); |
+ return key; |
+ } |
DCHECK(transition_number < number_of_transitions()); |
return Name::cast(get(ToKeyIndex(transition_number))); |
} |
-Name* TransitionArray::GetKey(Object* raw_transitions, int transition_number) { |
- if (IsSimpleTransition(raw_transitions)) { |
- DCHECK(transition_number == 0); |
- return GetSimpleTransitionKey(GetSimpleTransition(raw_transitions)); |
- } |
- DCHECK(IsFullTransitionArray(raw_transitions)); |
- return TransitionArray::cast(raw_transitions)->GetKey(transition_number); |
-} |
- |
- |
void TransitionArray::SetKey(int transition_number, Name* key) { |
+ DCHECK(!IsSimpleTransition()); |
DCHECK(transition_number < number_of_transitions()); |
set(ToKeyIndex(transition_number), key); |
} |
Map* TransitionArray::GetTarget(int transition_number) { |
+ if (IsSimpleTransition()) { |
+ DCHECK(transition_number == kSimpleTransitionIndex); |
+ return Map::cast(get(kSimpleTransitionTarget)); |
+ } |
DCHECK(transition_number < number_of_transitions()); |
return Map::cast(get(ToTargetIndex(transition_number))); |
} |
-Map* TransitionArray::GetTarget(Object* raw_transitions, |
- int transition_number) { |
- if (IsSimpleTransition(raw_transitions)) { |
- DCHECK(transition_number == 0); |
- return GetSimpleTransition(raw_transitions); |
- } |
- DCHECK(IsFullTransitionArray(raw_transitions)); |
- return TransitionArray::cast(raw_transitions)->GetTarget(transition_number); |
-} |
- |
- |
void TransitionArray::SetTarget(int transition_number, Map* value) { |
+ if (IsSimpleTransition()) { |
+ DCHECK(transition_number == kSimpleTransitionIndex); |
+ return set(kSimpleTransitionTarget, value); |
+ } |
DCHECK(transition_number < number_of_transitions()); |
set(ToTargetIndex(transition_number), value); |
} |
+PropertyDetails TransitionArray::GetTargetDetails(int transition_number) { |
+ Map* map = GetTarget(transition_number); |
+ return map->GetLastDescriptorDetails(); |
+} |
+ |
+ |
+Object* TransitionArray::GetTargetValue(int transition_number) { |
+ Map* map = GetTarget(transition_number); |
+ return map->instance_descriptors()->GetValue(map->LastAdded()); |
+} |
+ |
+ |
int TransitionArray::SearchName(Name* name, int* out_insertion_index) { |
+ if (IsSimpleTransition()) { |
+ Name* key = GetKey(kSimpleTransitionIndex); |
+ if (key->Equals(name)) return kSimpleTransitionIndex; |
+ if (out_insertion_index != NULL) { |
+ *out_insertion_index = key->Hash() > name->Hash() ? 0 : 1; |
+ } |
+ return kNotFound; |
+ } |
return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index); |
} |
@@ -169,9 +225,18 @@ |
void TransitionArray::SetNumberOfTransitions(int number_of_transitions) { |
- DCHECK(number_of_transitions <= Capacity(this)); |
- set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions)); |
-} |
+ if (IsFullTransitionArray()) { |
+ DCHECK(number_of_transitions <= number_of_transitions_storage()); |
+ WRITE_FIELD(this, kTransitionLengthOffset, |
+ Smi::FromInt(number_of_transitions)); |
+ } |
+} |
+ |
+ |
+#undef FIELD_ADDR |
+#undef WRITE_FIELD |
+#undef CONDITIONAL_WRITE_BARRIER |
+ |
} } // namespace v8::internal |