| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index ac7778f63c4c84af52f6240de7cb25bf6905b297..717a16a9cbe280125557d42d2191e967d18d5c5d 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -1900,8 +1900,7 @@
|
| old_map->GetHeap()->empty_descriptor_array(),
|
| LayoutDescriptor::FastPointerLayout());
|
| // Ensure that no transition was inserted for prototype migrations.
|
| - DCHECK_EQ(0, TransitionArray::NumberOfTransitions(
|
| - old_map->raw_transitions()));
|
| + DCHECK(!old_map->HasTransitionArray());
|
| DCHECK(new_map->GetBackPointer()->IsUndefined());
|
| }
|
| } else {
|
| @@ -2187,10 +2186,11 @@
|
|
|
| void Map::DeprecateTransitionTree() {
|
| if (is_deprecated()) return;
|
| - Object* transitions = raw_transitions();
|
| - int num_transitions = TransitionArray::NumberOfTransitions(transitions);
|
| - for (int i = 0; i < num_transitions; ++i) {
|
| - TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree();
|
| + if (HasTransitionArray()) {
|
| + TransitionArray* transitions = this->transitions();
|
| + for (int i = 0; i < transitions->number_of_transitions(); i++) {
|
| + transitions->GetTarget(i)->DeprecateTransitionTree();
|
| + }
|
| }
|
| deprecate();
|
| dependent_code()->DeoptimizeDependentCodeGroup(
|
| @@ -2215,11 +2215,13 @@
|
| DescriptorArray* new_descriptors,
|
| LayoutDescriptor* new_layout_descriptor) {
|
| bool transition_target_deprecated = false;
|
| - Map* maybe_transition =
|
| - TransitionArray::SearchTransition(this, kind, key, attributes);
|
| - if (maybe_transition != NULL) {
|
| - maybe_transition->DeprecateTransitionTree();
|
| - transition_target_deprecated = true;
|
| + if (HasTransitionArray()) {
|
| + TransitionArray* transitions = this->transitions();
|
| + int transition = transitions->Search(kind, key, attributes);
|
| + if (transition != TransitionArray::kNotFound) {
|
| + transitions->GetTarget(transition)->DeprecateTransitionTree();
|
| + transition_target_deprecated = true;
|
| + }
|
| }
|
|
|
| // Don't overwrite the empty descriptor array.
|
| @@ -2262,11 +2264,15 @@
|
| Map* current = this;
|
|
|
| for (int i = verbatim; i < length; i++) {
|
| + if (!current->HasTransitionArray()) break;
|
| Name* name = descriptors->GetKey(i);
|
| PropertyDetails details = descriptors->GetDetails(i);
|
| - Map* next = TransitionArray::SearchTransition(current, details.kind(), name,
|
| - details.attributes());
|
| - if (next == NULL) break;
|
| + TransitionArray* transitions = current->transitions();
|
| + int transition =
|
| + transitions->Search(details.kind(), name, details.attributes());
|
| + if (transition == TransitionArray::kNotFound) break;
|
| +
|
| + Map* next = transitions->GetTarget(transition);
|
| DescriptorArray* next_descriptors = next->instance_descriptors();
|
|
|
| PropertyDetails next_details = next_descriptors->GetDetails(i);
|
| @@ -2314,12 +2320,12 @@
|
| DisallowHeapAllocation no_allocation;
|
| PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
|
| if (details.type() != DATA) return;
|
| - Object* transitions = raw_transitions();
|
| - int num_transitions = TransitionArray::NumberOfTransitions(transitions);
|
| - for (int i = 0; i < num_transitions; ++i) {
|
| - Map* target = TransitionArray::GetTarget(transitions, i);
|
| - target->UpdateFieldType(descriptor, name, new_representation,
|
| - new_wrapped_type);
|
| + if (HasTransitionArray()) {
|
| + TransitionArray* transitions = this->transitions();
|
| + for (int i = 0; i < transitions->number_of_transitions(); ++i) {
|
| + transitions->GetTarget(i)->UpdateFieldType(
|
| + descriptor, name, new_representation, new_wrapped_type);
|
| + }
|
| }
|
| // It is allowed to change representation here only from None to something.
|
| DCHECK(details.representation().Equals(new_representation) ||
|
| @@ -2559,11 +2565,10 @@
|
| next_attributes = old_details.attributes();
|
| next_representation = old_details.representation();
|
| }
|
| - Map* transition = TransitionArray::SearchTransition(
|
| - *target_map, next_kind, old_descriptors->GetKey(i), next_attributes);
|
| - if (transition == NULL) break;
|
| - Handle<Map> tmp_map(transition, isolate);
|
| -
|
| + int j = target_map->SearchTransition(next_kind, old_descriptors->GetKey(i),
|
| + next_attributes);
|
| + if (j == TransitionArray::kNotFound) break;
|
| + Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
|
| Handle<DescriptorArray> tmp_descriptors = handle(
|
| tmp_map->instance_descriptors(), isolate);
|
|
|
| @@ -2648,10 +2653,10 @@
|
| next_kind = old_details.kind();
|
| next_attributes = old_details.attributes();
|
| }
|
| - Map* transition = TransitionArray::SearchTransition(
|
| - *target_map, next_kind, old_descriptors->GetKey(i), next_attributes);
|
| - if (transition == NULL) break;
|
| - Handle<Map> tmp_map(transition, isolate);
|
| + int j = target_map->SearchTransition(next_kind, old_descriptors->GetKey(i),
|
| + next_attributes);
|
| + if (j == TransitionArray::kNotFound) break;
|
| + Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
|
| Handle<DescriptorArray> tmp_descriptors(
|
| tmp_map->instance_descriptors(), isolate);
|
|
|
| @@ -2889,8 +2894,7 @@
|
| // If |transition_target_deprecated| is true then the transition array
|
| // already contains entry for given descriptor. This means that the transition
|
| // could be inserted regardless of whether transitions array is full or not.
|
| - if (!transition_target_deprecated &&
|
| - !TransitionArray::CanHaveMoreTransitions(split_map)) {
|
| + if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) {
|
| return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
|
| new_kind, new_attributes,
|
| "GenAll_CantHaveMoreTransitions");
|
| @@ -2963,11 +2967,11 @@
|
| Map* new_map = root_map;
|
| for (int i = root_nof; i < old_nof; ++i) {
|
| PropertyDetails old_details = old_descriptors->GetDetails(i);
|
| - Map* transition = TransitionArray::SearchTransition(
|
| - new_map, old_details.kind(), old_descriptors->GetKey(i),
|
| - old_details.attributes());
|
| - if (transition == NULL) return MaybeHandle<Map>();
|
| - new_map = transition;
|
| + int j = new_map->SearchTransition(old_details.kind(),
|
| + old_descriptors->GetKey(i),
|
| + old_details.attributes());
|
| + if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
|
| + new_map = new_map->GetTransition(j);
|
| DescriptorArray* new_descriptors = new_map->instance_descriptors();
|
|
|
| PropertyDetails new_details = new_descriptors->GetDetails(i);
|
| @@ -3609,9 +3613,9 @@
|
| // have the cached transition.
|
| if (IsExternalArrayElementsKind(to_kind) &&
|
| !IsFixedTypedArrayElementsKind(map->elements_kind())) {
|
| - Map* next_map = map->ElementsTransitionMap();
|
| - if (next_map != NULL && next_map->elements_kind() == to_kind) {
|
| - return next_map;
|
| + if (map->HasElementsTransition()) {
|
| + Map* next_map = map->elements_transition_map();
|
| + if (next_map->elements_kind() == to_kind) return next_map;
|
| }
|
| return map;
|
| }
|
| @@ -3619,14 +3623,13 @@
|
| ElementsKind kind = map->elements_kind();
|
| while (kind != target_kind) {
|
| kind = GetNextTransitionElementsKind(kind);
|
| - Map* next_map = current_map->ElementsTransitionMap();
|
| - if (next_map == NULL) return current_map;
|
| - current_map = next_map;
|
| - }
|
| -
|
| - Map* next_map = current_map->ElementsTransitionMap();
|
| - if (to_kind != kind && next_map != NULL) {
|
| + if (!current_map->HasElementsTransition()) return current_map;
|
| + current_map = current_map->elements_transition_map();
|
| + }
|
| +
|
| + if (to_kind != kind && current_map->HasElementsTransition()) {
|
| DCHECK(to_kind == DICTIONARY_ELEMENTS);
|
| + Map* next_map = current_map->elements_transition_map();
|
| if (next_map->elements_kind() == to_kind) return next_map;
|
| }
|
|
|
| @@ -5726,15 +5729,13 @@
|
| }
|
|
|
| Handle<Map> old_map(object->map(), isolate);
|
| - Map* transition =
|
| - TransitionArray::SearchSpecial(*old_map, *transition_marker);
|
| - if (transition != NULL) {
|
| - Handle<Map> transition_map(transition, isolate);
|
| + int transition_index = old_map->SearchSpecialTransition(*transition_marker);
|
| + if (transition_index != TransitionArray::kNotFound) {
|
| + Handle<Map> transition_map(old_map->GetTransition(transition_index));
|
| DCHECK(transition_map->has_dictionary_elements());
|
| DCHECK(!transition_map->is_extensible());
|
| JSObject::MigrateToMap(object, transition_map);
|
| - } else if (object->HasFastProperties() &&
|
| - TransitionArray::CanHaveMoreTransitions(old_map)) {
|
| + } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
|
| // Create a new descriptor array with the appropriate property attributes
|
| Handle<Map> new_map = Map::CopyForPreventExtensions(
|
| old_map, attrs, transition_marker, "CopyForPreventExtensions");
|
| @@ -5793,13 +5794,12 @@
|
| Handle<Map> new_map;
|
| Handle<Map> old_map(object->map(), isolate);
|
| DCHECK(!old_map->is_observed());
|
| - Map* transition = TransitionArray::SearchSpecial(
|
| - *old_map, isolate->heap()->observed_symbol());
|
| - if (transition != NULL) {
|
| - new_map = handle(transition, isolate);
|
| + int transition_index =
|
| + old_map->SearchSpecialTransition(isolate->heap()->observed_symbol());
|
| + if (transition_index != TransitionArray::kNotFound) {
|
| + new_map = handle(old_map->GetTransition(transition_index), isolate);
|
| DCHECK(new_map->is_observed());
|
| - } else if (object->HasFastProperties() &&
|
| - TransitionArray::CanHaveMoreTransitions(old_map)) {
|
| + } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
|
| new_map = Map::CopyForObserved(old_map);
|
| } else {
|
| new_map = Map::Copy(old_map, "SlowObserved");
|
| @@ -7018,12 +7018,11 @@
|
|
|
| // static
|
| void Map::TraceAllTransitions(Map* map) {
|
| - Object* transitions = map->raw_transitions();
|
| - int num_transitions = TransitionArray::NumberOfTransitions(transitions);
|
| - for (int i = -0; i < num_transitions; ++i) {
|
| - Map* target = TransitionArray::GetTarget(transitions, i);
|
| - Name* key = TransitionArray::GetKey(transitions, i);
|
| - Map::TraceTransition("Transition", map, target, key);
|
| + if (!map->HasTransitionArray()) return;
|
| + TransitionArray* transitions = map->transitions();
|
| + for (int i = 0; i < transitions->number_of_transitions(); ++i) {
|
| + Map* target = transitions->GetTarget(i);
|
| + Map::TraceTransition("Transition", map, target, transitions->GetKey(i));
|
| Map::TraceAllTransitions(target);
|
| }
|
| }
|
| @@ -7040,7 +7039,13 @@
|
| Map::TraceTransition("NoTransition", *parent, *child, *name);
|
| #endif
|
| } else {
|
| - TransitionArray::Insert(parent, name, child, flag);
|
| + Handle<TransitionArray> transitions =
|
| + TransitionArray::Insert(parent, name, child, flag);
|
| + if (!parent->HasTransitionArray() ||
|
| + *transitions != parent->transitions()) {
|
| + parent->set_transitions(*transitions);
|
| + }
|
| + child->SetBackPointer(*parent);
|
| if (child->prototype()->IsJSObject()) {
|
| Handle<JSObject> proto(JSObject::cast(child->prototype()));
|
| if (!child->ShouldRegisterAsPrototypeUser(proto)) {
|
| @@ -7064,8 +7069,7 @@
|
| Handle<Map> result = CopyDropDescriptors(map);
|
|
|
| if (!map->is_prototype_map()) {
|
| - if (flag == INSERT_TRANSITION &&
|
| - TransitionArray::CanHaveMoreTransitions(map)) {
|
| + if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
|
| result->InitializeDescriptors(*descriptors, *layout_descriptor);
|
|
|
| Handle<Name> name;
|
| @@ -7089,8 +7093,7 @@
|
| if (FLAG_trace_maps &&
|
| // Mirror conditions above that did not call ConnectTransition().
|
| (map->is_prototype_map() ||
|
| - !(flag == INSERT_TRANSITION &&
|
| - TransitionArray::CanHaveMoreTransitions(map)))) {
|
| + !(flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()))) {
|
| PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n",
|
| reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result),
|
| reason);
|
| @@ -7148,24 +7151,22 @@
|
|
|
| Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
|
| TransitionFlag flag) {
|
| - Map* maybe_elements_transition_map = NULL;
|
| if (flag == INSERT_TRANSITION) {
|
| - maybe_elements_transition_map = map->ElementsTransitionMap();
|
| - DCHECK(
|
| - maybe_elements_transition_map == NULL ||
|
| - ((maybe_elements_transition_map->elements_kind() ==
|
| - DICTIONARY_ELEMENTS ||
|
| + DCHECK(!map->HasElementsTransition() ||
|
| + ((map->elements_transition_map()->elements_kind() ==
|
| + DICTIONARY_ELEMENTS ||
|
| IsExternalArrayElementsKind(
|
| - maybe_elements_transition_map->elements_kind())) &&
|
| - (kind == DICTIONARY_ELEMENTS || IsExternalArrayElementsKind(kind))));
|
| + map->elements_transition_map()->elements_kind())) &&
|
| + (kind == DICTIONARY_ELEMENTS ||
|
| + IsExternalArrayElementsKind(kind))));
|
| DCHECK(!IsFastElementsKind(kind) ||
|
| IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
|
| DCHECK(kind != map->elements_kind());
|
| }
|
|
|
| bool insert_transition = flag == INSERT_TRANSITION &&
|
| - TransitionArray::CanHaveMoreTransitions(map) &&
|
| - maybe_elements_transition_map == NULL;
|
| + map->CanHaveMoreTransitions() &&
|
| + !map->HasElementsTransition();
|
|
|
| if (insert_transition) {
|
| Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind");
|
| @@ -7189,7 +7190,7 @@
|
| Isolate* isolate = map->GetIsolate();
|
|
|
| bool insert_transition =
|
| - TransitionArray::CanHaveMoreTransitions(map) && !map->is_prototype_map();
|
| + map->CanHaveMoreTransitions() && !map->is_prototype_map();
|
|
|
| if (insert_transition) {
|
| Handle<Map> new_map = CopyForTransition(map, "CopyForObserved");
|
| @@ -7355,10 +7356,9 @@
|
| // Migrate to the newest map before storing the property.
|
| map = Update(map);
|
|
|
| - Map* maybe_transition =
|
| - TransitionArray::SearchTransition(*map, kData, *name, attributes);
|
| - if (maybe_transition != NULL) {
|
| - Handle<Map> transition(maybe_transition);
|
| + int index = map->SearchTransition(kData, *name, attributes);
|
| + if (index != TransitionArray::kNotFound) {
|
| + Handle<Map> transition(map->GetTransition(index));
|
| int descriptor = transition->LastAdded();
|
|
|
| DCHECK_EQ(attributes, transition->instance_descriptors()
|
| @@ -7447,10 +7447,9 @@
|
| ? KEEP_INOBJECT_PROPERTIES
|
| : CLEAR_INOBJECT_PROPERTIES;
|
|
|
| - Map* maybe_transition =
|
| - TransitionArray::SearchTransition(*map, kAccessor, *name, attributes);
|
| - if (maybe_transition != NULL) {
|
| - Handle<Map> transition(maybe_transition, isolate);
|
| + int index = map->SearchTransition(kAccessor, *name, attributes);
|
| + if (index != TransitionArray::kNotFound) {
|
| + Handle<Map> transition(map->GetTransition(index));
|
| DescriptorArray* descriptors = transition->instance_descriptors();
|
| int descriptor = transition->LastAdded();
|
| DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
|
| @@ -7522,8 +7521,9 @@
|
| // Ensure the key is unique.
|
| descriptor->KeyToUniqueName();
|
|
|
| - if (flag == INSERT_TRANSITION && map->owns_descriptors() &&
|
| - TransitionArray::CanHaveMoreTransitions(map)) {
|
| + if (flag == INSERT_TRANSITION &&
|
| + map->owns_descriptors() &&
|
| + map->CanHaveMoreTransitions()) {
|
| return ShareDescriptor(map, descriptors, descriptor);
|
| }
|
|
|
| @@ -7684,6 +7684,38 @@
|
| // RemoveFromCodeCache so the code cache must be there.
|
| DCHECK(!code_cache()->IsFixedArray());
|
| CodeCache::cast(code_cache())->RemoveByIndex(name, code, index);
|
| +}
|
| +
|
| +
|
| +static void TraverseTransitionTreeInternal(Map* map,
|
| + Map::TraverseCallback callback,
|
| + void* data) {
|
| + if (map->HasTransitionArray()) {
|
| + TransitionArray* transitions = map->transitions();
|
| + if (transitions->HasPrototypeTransitions()) {
|
| + FixedArray* proto_trans = transitions->GetPrototypeTransitions();
|
| + Object* num_obj =
|
| + proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset);
|
| + int num = Smi::cast(num_obj)->value();
|
| + for (int i = 0; i < num; ++i) {
|
| + int index = Map::kProtoTransitionHeaderSize + i;
|
| + TraverseTransitionTreeInternal(Map::cast(proto_trans->get(index)),
|
| + callback, data);
|
| + }
|
| + }
|
| + for (int i = 0; i < transitions->number_of_transitions(); ++i) {
|
| + TraverseTransitionTreeInternal(transitions->GetTarget(i), callback, data);
|
| + }
|
| + }
|
| + callback(map, data);
|
| +}
|
| +
|
| +
|
| +// Traverse the transition tree in postorder.
|
| +void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
|
| + // Make sure that we do not allocate in the callback.
|
| + DisallowHeapAllocation no_allocation;
|
| + TraverseTransitionTreeInternal(this, callback, data);
|
| }
|
|
|
|
|
| @@ -9860,10 +9892,10 @@
|
| map->set_counter(Map::kRetainingCounterStart);
|
|
|
| int slack = map->unused_property_fields();
|
| - TransitionArray::TraverseTransitionTree(map, &GetMinInobjectSlack, &slack);
|
| + map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
|
| if (slack != 0) {
|
| // Resize the initial map and all maps in its transition tree.
|
| - TransitionArray::TraverseTransitionTree(map, &ShrinkInstanceSize, &slack);
|
| + map->TraverseTransitionTree(&ShrinkInstanceSize, &slack);
|
| }
|
| }
|
|
|
| @@ -10016,9 +10048,8 @@
|
| i < kFastElementsKindCount; ++i) {
|
| Handle<Map> new_map;
|
| ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
|
| - Map* maybe_elements_transition = current_map->ElementsTransitionMap();
|
| - if (maybe_elements_transition != NULL) {
|
| - new_map = handle(maybe_elements_transition);
|
| + if (current_map->HasElementsTransition()) {
|
| + new_map = handle(current_map->elements_transition_map());
|
| DCHECK(new_map->elements_kind() == next_kind);
|
| } else {
|
| new_map = Map::CopyAsElementsKind(
|
| @@ -11939,6 +11970,77 @@
|
| }
|
|
|
|
|
| +Handle<Map> Map::GetPrototypeTransition(Handle<Map> map,
|
| + Handle<Object> prototype) {
|
| + DisallowHeapAllocation no_gc;
|
| + FixedArray* cache = map->GetPrototypeTransitions();
|
| + int number_of_transitions = map->NumberOfProtoTransitions();
|
| + for (int i = 0; i < number_of_transitions; i++) {
|
| + Map* map = Map::cast(cache->get(kProtoTransitionHeaderSize + i));
|
| + if (map->prototype() == *prototype) return handle(map);
|
| + }
|
| + return Handle<Map>();
|
| +}
|
| +
|
| +
|
| +Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
|
| + Handle<Object> prototype,
|
| + Handle<Map> target_map) {
|
| + DCHECK(target_map->IsMap());
|
| + DCHECK(HeapObject::cast(*prototype)->map()->IsMap());
|
| + // Don't cache prototype transition if this map is either shared, or a map of
|
| + // a prototype.
|
| + if (map->is_prototype_map()) return map;
|
| + if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return map;
|
| +
|
| + const int header = kProtoTransitionHeaderSize;
|
| +
|
| + Handle<FixedArray> cache(map->GetPrototypeTransitions());
|
| + int capacity = cache->length() - header;
|
| + int transitions = map->NumberOfProtoTransitions() + 1;
|
| +
|
| + if (transitions > capacity) {
|
| + // Grow array by factor 2 up to MaxCachedPrototypeTransitions.
|
| + int new_capacity = Min(kMaxCachedPrototypeTransitions, transitions * 2);
|
| + if (new_capacity == capacity) return map;
|
| +
|
| + cache = FixedArray::CopySize(cache, header + new_capacity);
|
| +
|
| + SetPrototypeTransitions(map, cache);
|
| + }
|
| +
|
| + // Reload number of transitions as GC might shrink them.
|
| + int last = map->NumberOfProtoTransitions();
|
| + int entry = header + last;
|
| +
|
| + cache->set(entry, *target_map);
|
| + map->SetNumberOfProtoTransitions(last + 1);
|
| +
|
| + return map;
|
| +}
|
| +
|
| +
|
| +void Map::ZapTransitions() {
|
| + TransitionArray* transition_array = transitions();
|
| + // TODO(mstarzinger): Temporarily use a slower version instead of the faster
|
| + // MemsetPointer to investigate a crasher. Switch back to MemsetPointer.
|
| + Object** data = transition_array->data_start();
|
| + Object* the_hole = GetHeap()->the_hole_value();
|
| + int length = transition_array->length();
|
| + for (int i = 0; i < length; i++) {
|
| + data[i] = the_hole;
|
| + }
|
| +}
|
| +
|
| +
|
| +void Map::ZapPrototypeTransitions() {
|
| + FixedArray* proto_transitions = GetPrototypeTransitions();
|
| + MemsetPointer(proto_transitions->data_start(),
|
| + GetHeap()->the_hole_value(),
|
| + proto_transitions->length());
|
| +}
|
| +
|
| +
|
| // static
|
| void Map::AddDependentCompilationInfo(Handle<Map> map,
|
| DependentCode::DependencyGroup group,
|
| @@ -12244,10 +12346,10 @@
|
| Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
|
| Handle<Object> prototype,
|
| PrototypeOptimizationMode mode) {
|
| - Handle<Map> new_map = TransitionArray::GetPrototypeTransition(map, prototype);
|
| + Handle<Map> new_map = GetPrototypeTransition(map, prototype);
|
| if (new_map.is_null()) {
|
| new_map = Copy(map, "TransitionToPrototype");
|
| - TransitionArray::PutPrototypeTransition(map, prototype, new_map);
|
| + PutPrototypeTransition(map, prototype, new_map);
|
| new_map->SetPrototype(prototype, mode);
|
| }
|
| return new_map;
|
|
|