Index: src/transitions.cc |
diff --git a/src/transitions.cc b/src/transitions.cc |
index 9d3f038947d139694ae7a5563d42a4792484438f..7b3a0982f9f031e4b6ac1a133e1c77609fe86eb7 100644 |
--- a/src/transitions.cc |
+++ b/src/transitions.cc |
@@ -44,6 +44,14 @@ static MaybeObject* AllocateRaw(Isolate* isolate, int length) { |
} |
+static Handle<TransitionArray> AllocateRawHandle(Isolate* isolate, int length) { |
+ // Use FixedArray to not use TransitionArray::cast on incomplete object. |
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
+ return Handle<TransitionArray>::cast(array); |
+} |
+ |
+ |
+ |
MaybeObject* TransitionArray::Allocate(Isolate* isolate, |
int number_of_transitions) { |
FixedArray* array; |
@@ -69,6 +77,25 @@ static bool InsertionPointFound(Name* key1, Name* key2) { |
} |
+Handle<TransitionArray> TransitionArray::NewWithHandle( |
+ SimpleTransitionFlag flag, |
+ Handle<Name> key, |
+ Handle<Map> target, |
+ Handle<Object> back_pointer) { |
+ Handle<TransitionArray> result; |
+ |
+ if (flag == SIMPLE_TRANSITION) { |
+ result = AllocateRawHandle(target->GetIsolate(), kSimpleTransitionSize); |
+ result->set(kSimpleTransitionTarget, *target); |
+ } else { |
+ result = AllocateHandle(target->GetIsolate(), 1); |
+ result->NoIncrementalWriteBarrierSet(0, *key, *target); |
+ } |
+ result->set_back_pointer_storage(*back_pointer); |
+ return result; |
+} |
+ |
+ |
MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag, |
Name* key, |
Map* target, |
@@ -106,12 +133,19 @@ MaybeObject* TransitionArray::ExtendToFullTransitionArray() { |
} |
+Handle<TransitionArray> TransitionArray::AllocateHandle( |
+ Isolate* isolate, int number_of_transitions) { |
+ Handle<FixedArray> array = |
+ isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions)); |
+ array->set(kPrototypeTransitionsIndex, Smi::FromInt(0)); |
+ return Handle<TransitionArray>::cast(array); |
+} |
+ |
+ |
MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) { |
TransitionArray* result; |
- |
int number_of_transitions = this->number_of_transitions(); |
int new_size = number_of_transitions; |
- |
int insertion_index = this->Search(name); |
if (insertion_index == kNotFound) ++new_size; |
@@ -153,4 +187,52 @@ MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) { |
} |
+Handle<TransitionArray> TransitionArray::CopyInsert( |
+ Handle<TransitionArray> array, |
+ Handle<Name> name, |
+ Handle<Map> target) { |
+ Handle<TransitionArray> result; |
+ |
+ int number_of_transitions = array->number_of_transitions(); |
+ int new_size = number_of_transitions; |
+ |
+ int insertion_index = array->Search(*name); |
+ if (insertion_index == kNotFound) ++new_size; |
+ |
+ result = TransitionArray::AllocateHandle(array->GetIsolate(), new_size); |
+ |
+ if (array->HasPrototypeTransitions()) { |
+ result->SetPrototypeTransitions(array->GetPrototypeTransitions()); |
+ } |
+ |
+ if (insertion_index != kNotFound) { |
+ for (int i = 0; i < number_of_transitions; ++i) { |
Toon Verwaest
2014/04/08 12:58:55
Wrong. number_of_transitions can change because of
mvstanton
2014/04/09 09:43:20
Done.
|
+ 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; |
+ result->NoIncrementalWriteBarrierCopyFrom( |
+ *array, insertion_index, insertion_index); |
+ } |
+ |
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); |
+ |
+ for (; insertion_index < number_of_transitions; ++insertion_index) { |
+ result->NoIncrementalWriteBarrierCopyFrom( |
+ *array, insertion_index, insertion_index + 1); |
+ } |
+ |
+ result->set_back_pointer_storage(array->back_pointer_storage()); |
+ return result; |
+} |
+ |
+ |
} } // namespace v8::internal |