Index: src/transitions.cc |
diff --git a/src/transitions.cc b/src/transitions.cc |
index 5e6d4106fc06bc917c3f3620f570604ea71b2cb4..96ed870e07b43465bccef7b29abe24b7305f246e 100644 |
--- a/src/transitions.cc |
+++ b/src/transitions.cc |
@@ -13,12 +13,10 @@ namespace internal { |
Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate, |
- int number_of_transitions, |
- int slack) { |
- Handle<FixedArray> array = isolate->factory()->NewFixedArray( |
- LengthFor(number_of_transitions + slack)); |
+ int number_of_transitions) { |
+ Handle<FixedArray> array = |
+ isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions)); |
array->set(kPrototypeTransitionsIndex, Smi::FromInt(0)); |
- array->set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions)); |
return Handle<TransitionArray>::cast(array); |
} |
@@ -76,7 +74,6 @@ Handle<TransitionArray> TransitionArray::ExtendToFullTransitionArray( |
if (new_nof != nof) { |
DCHECK(new_nof == 0); |
result->Shrink(ToKeyIndex(0)); |
- result->SetNumberOfTransitions(0); |
} else if (nof == 1) { |
result->NoIncrementalWriteBarrierCopyFrom( |
containing_map->transitions(), kSimpleTransitionIndex, 0); |
@@ -88,47 +85,21 @@ Handle<TransitionArray> TransitionArray::ExtendToFullTransitionArray( |
} |
-Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map, |
- Handle<Name> name, |
- Handle<Map> target, |
- SimpleTransitionFlag flag) { |
+Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, |
+ Handle<Name> name, |
+ Handle<Map> target, |
+ SimpleTransitionFlag flag) { |
if (!map->HasTransitionArray()) { |
return TransitionArray::NewWith(map, name, target, flag); |
} |
int number_of_transitions = map->transitions()->number_of_transitions(); |
- int new_nof = number_of_transitions; |
+ int new_size = number_of_transitions; |
int insertion_index = map->transitions()->Search(*name); |
- if (insertion_index == kNotFound) ++new_nof; |
- DCHECK(new_nof <= kMaxNumberOfTransitions); |
- |
- if (new_nof <= map->transitions()->number_of_transitions_storage()) { |
- DisallowHeapAllocation no_gc; |
- TransitionArray* array = map->transitions(); |
- |
- if (insertion_index != kNotFound) { |
- array->SetTarget(insertion_index, *target); |
- return handle(array); |
- } |
- |
- array->SetNumberOfTransitions(new_nof); |
- uint32_t hash = name->Hash(); |
- for (insertion_index = number_of_transitions; insertion_index > 0; |
- --insertion_index) { |
- Name* key = array->GetKey(insertion_index - 1); |
- if (key->Hash() <= hash) break; |
- array->SetKey(insertion_index, key); |
- array->SetTarget(insertion_index, array->GetTarget(insertion_index - 1)); |
- } |
- array->SetKey(insertion_index, *name); |
- array->SetTarget(insertion_index, *target); |
- return handle(array); |
- } |
+ if (insertion_index == kNotFound) ++new_size; |
- Handle<TransitionArray> result = Allocate( |
- map->GetIsolate(), new_nof, |
- Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions)); |
+ Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size); |
// The map's transition array may grown smaller during the allocation above as |
// it was weakly traversed, though it is guaranteed not to disappear. Trim the |
@@ -140,19 +111,29 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map, |
DCHECK(array->number_of_transitions() < number_of_transitions); |
number_of_transitions = array->number_of_transitions(); |
- new_nof = number_of_transitions; |
+ new_size = number_of_transitions; |
insertion_index = array->Search(*name); |
- if (insertion_index == kNotFound) ++new_nof; |
+ if (insertion_index == kNotFound) ++new_size; |
- result->Shrink(ToKeyIndex(new_nof)); |
- result->SetNumberOfTransitions(new_nof); |
+ result->Shrink(ToKeyIndex(new_size)); |
} |
if (array->HasPrototypeTransitions()) { |
result->SetPrototypeTransitions(array->GetPrototypeTransitions()); |
} |
+ if (insertion_index != kNotFound) { |
+ for (int i = 0; i < number_of_transitions; ++i) { |
+ if (i != insertion_index) { |
+ result->NoIncrementalWriteBarrierCopyFrom(array, i, i); |
+ } |
+ } |
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); |
+ result->set_back_pointer_storage(array->back_pointer_storage()); |
+ return result; |
+ } |
+ |
insertion_index = 0; |
for (; insertion_index < number_of_transitions; ++insertion_index) { |
if (InsertionPointFound(array->GetKey(insertion_index), *name)) break; |