Index: src/objects-inl.h |
diff --git a/src/objects-inl.h b/src/objects-inl.h |
index 0620e0e876ed6cb7754d35f342bfc8ed5117efc9..efa6259bd75a6286ab04dd397f34843cf77d3bda 100644 |
--- a/src/objects-inl.h |
+++ b/src/objects-inl.h |
@@ -1871,9 +1871,14 @@ Object** FixedArray::data_start() { |
bool DescriptorArray::IsEmpty() { |
ASSERT(this->IsSmi() || |
- this->length() > kFirstIndex || |
+ this->MayContainTransitions() || |
this == HEAP->empty_descriptor_array()); |
- return this->IsSmi() || length() <= kFirstIndex; |
+ return this->IsSmi() || length() < kFirstIndex; |
+} |
+ |
+ |
+bool DescriptorArray::MayContainTransitions() { |
+ return length() >= kTransitionsIndex; |
} |
@@ -1883,7 +1888,7 @@ int DescriptorArray::bit_field3_storage() { |
} |
void DescriptorArray::set_bit_field3_storage(int value) { |
- ASSERT(!IsEmpty()); |
+ ASSERT(this->MayContainTransitions()); |
WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value)); |
} |
@@ -1907,7 +1912,7 @@ int DescriptorArray::Search(String* name) { |
// Fast case: do linear search for small arrays. |
const int kMaxElementsForLinearSearch = 8; |
if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) { |
- return LinearSearch(name, nof); |
+ return LinearSearch(EXPECT_SORTED, name, nof); |
} |
// Slow case: perform binary search. |
@@ -1925,6 +1930,30 @@ int DescriptorArray::SearchWithCache(String* name) { |
} |
+Map* DescriptorArray::elements_transition_map() { |
+ if (!this->MayContainTransitions()) { |
+ return NULL; |
+ } |
+ Object* transition_map = get(kTransitionsIndex); |
+ if (transition_map == Smi::FromInt(0)) { |
+ return NULL; |
+ } else { |
+ return Map::cast(transition_map); |
+ } |
+} |
+ |
+ |
+void DescriptorArray::set_elements_transition_map( |
+ Map* transition_map, WriteBarrierMode mode) { |
+ ASSERT(this->length() > kTransitionsIndex); |
+ Heap* heap = GetHeap(); |
+ WRITE_FIELD(this, kTransitionsOffset, transition_map); |
+ CONDITIONAL_WRITE_BARRIER( |
+ heap, this, kTransitionsOffset, transition_map, mode); |
+ ASSERT(DescriptorArray::cast(this)); |
+} |
+ |
+ |
Object** DescriptorArray::GetKeySlot(int descriptor_number) { |
ASSERT(descriptor_number < number_of_descriptors()); |
return HeapObject::RawField( |
@@ -2010,7 +2039,6 @@ bool DescriptorArray::IsTransitionOnly(int descriptor_number) { |
switch (GetType(descriptor_number)) { |
case MAP_TRANSITION: |
case CONSTANT_TRANSITION: |
- case ELEMENTS_TRANSITION: |
return true; |
case CALLBACKS: { |
Object* value = GetValue(descriptor_number); |
@@ -3452,6 +3480,16 @@ Object* Map::GetBackPointer() { |
} |
+Map* Map::elements_transition_map() { |
+ return instance_descriptors()->elements_transition_map(); |
+} |
+ |
+ |
+void Map::set_elements_transition_map(Map* transitioned_map) { |
+ return instance_descriptors()->set_elements_transition_map(transitioned_map); |
+} |
+ |
+ |
void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { |
Heap* heap = GetHeap(); |
ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); |
@@ -4049,15 +4087,12 @@ MaybeObject* JSFunction::set_initial_map_and_cache_transitions( |
maps->set(kind, current_map); |
for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
i < kFastElementsKindCount; ++i) { |
- ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i); |
- MaybeObject* maybe_new_map = current_map->CopyDropTransitions(); |
- Map* new_map = NULL; |
- if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; |
- new_map->set_elements_kind(transitioned_kind); |
- maybe_new_map = current_map->AddElementsTransition(transitioned_kind, |
- new_map); |
- if (maybe_new_map->IsFailure()) return maybe_new_map; |
- maps->set(transitioned_kind, new_map); |
+ Map* new_map; |
+ ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
+ MaybeObject* maybe_new_map = |
+ current_map->CreateNextElementsTransition(next_kind); |
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ maps->set(next_kind, new_map); |
current_map = new_map; |
} |
global_context->set_js_array_maps(maps); |