Index: src/transitions.cc |
diff --git a/src/transitions.cc b/src/transitions.cc |
index 9d3f038947d139694ae7a5563d42a4792484438f..76af6d550ee73c82d282edcd0214f2c1aaeb573a 100644 |
--- a/src/transitions.cc |
+++ b/src/transitions.cc |
@@ -55,6 +55,17 @@ MaybeObject* TransitionArray::Allocate(Isolate* isolate, |
} |
+MaybeObject* TransitionArray::AllocateSimple(Isolate* isolate, |
+ Map* target) { |
+ FixedArray* array; |
+ MaybeObject* maybe_array = |
+ AllocateRaw(isolate, kSimpleTransitionSize); |
+ if (!maybe_array->To(&array)) return maybe_array; |
+ array->set(kSimpleTransitionTarget, target); |
+ return array; |
+} |
+ |
+ |
void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin, |
int origin_transition, |
int target_transition) { |
@@ -69,23 +80,20 @@ static bool InsertionPointFound(Name* key1, Name* key2) { |
} |
-MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag, |
- Name* key, |
- Map* target, |
- Object* back_pointer) { |
- TransitionArray* result; |
- MaybeObject* maybe_result; |
+Handle<TransitionArray> TransitionArray::NewWith(SimpleTransitionFlag flag, |
+ Handle<Name> key, |
+ Handle<Map> target, |
+ Handle<Object> back_pointer) { |
+ Handle<TransitionArray> result; |
+ Factory* factory = key->GetIsolate()->factory(); |
if (flag == SIMPLE_TRANSITION) { |
- maybe_result = AllocateRaw(target->GetIsolate(), kSimpleTransitionSize); |
- if (!maybe_result->To(&result)) return maybe_result; |
- result->set(kSimpleTransitionTarget, target); |
+ result = factory->NewSimpleTransitionArray(target); |
} else { |
- maybe_result = Allocate(target->GetIsolate(), 1); |
- if (!maybe_result->To(&result)) return maybe_result; |
- result->NoIncrementalWriteBarrierSet(0, key, target); |
+ result = factory->NewTransitionArray(1); |
+ result->NoIncrementalWriteBarrierSet(0, *key, *target); |
} |
- result->set_back_pointer_storage(back_pointer); |
+ result->set_back_pointer_storage(*back_pointer); |
return result; |
} |
@@ -106,49 +114,67 @@ MaybeObject* TransitionArray::ExtendToFullTransitionArray() { |
} |
-MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) { |
- TransitionArray* result; |
+Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, |
+ Handle<Name> name, |
+ Handle<Map> target) { |
+ ASSERT(map->HasTransitionArray()); |
+ Handle<TransitionArray> result; |
- int number_of_transitions = this->number_of_transitions(); |
+ int number_of_transitions = map->transitions()->number_of_transitions(); |
int new_size = number_of_transitions; |
- int insertion_index = this->Search(name); |
+ int insertion_index = map->transitions()->Search(*name); |
if (insertion_index == kNotFound) ++new_size; |
- MaybeObject* maybe_array; |
- maybe_array = TransitionArray::Allocate(GetIsolate(), new_size); |
- if (!maybe_array->To(&result)) return maybe_array; |
+ result = map->GetIsolate()->factory()->NewTransitionArray(new_size); |
+ |
+ // The map's transition array may have grown smaller during the allocation |
+ // above as it was weakly traversed. Trim the result copy if needed, and |
+ // recompute variables. |
+ DisallowHeapAllocation no_gc; |
+ TransitionArray* array = map->transitions(); |
+ if (array->number_of_transitions() != number_of_transitions) { |
+ ASSERT(array->number_of_transitions() < number_of_transitions); |
+ |
+ number_of_transitions = array->number_of_transitions(); |
+ new_size = number_of_transitions; |
+ |
+ insertion_index = array->Search(*name); |
+ if (insertion_index == kNotFound) ++new_size; |
- if (HasPrototypeTransitions()) { |
- result->SetPrototypeTransitions(GetPrototypeTransitions()); |
+ result->Shrink(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(this, i, i); |
+ result->NoIncrementalWriteBarrierCopyFrom(array, i, i); |
} |
} |
- result->NoIncrementalWriteBarrierSet(insertion_index, name, target); |
- result->set_back_pointer_storage(back_pointer_storage()); |
+ 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(GetKey(insertion_index), name)) break; |
+ if (InsertionPointFound(array->GetKey(insertion_index), *name)) break; |
result->NoIncrementalWriteBarrierCopyFrom( |
- this, insertion_index, insertion_index); |
+ array, insertion_index, insertion_index); |
} |
- result->NoIncrementalWriteBarrierSet(insertion_index, name, target); |
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); |
for (; insertion_index < number_of_transitions; ++insertion_index) { |
result->NoIncrementalWriteBarrierCopyFrom( |
- this, insertion_index, insertion_index + 1); |
+ array, insertion_index, insertion_index + 1); |
} |
- result->set_back_pointer_storage(back_pointer_storage()); |
+ result->set_back_pointer_storage(array->back_pointer_storage()); |
return result; |
} |