From 5883de41ccdc858f00c28740ddfaf613e9ea8809 Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Mon, 5 May 2014 09:57:45 +0000 Subject: [PATCH] Map::TransitionElementsTo() extracted from JSObject::GetElementsTransitionMap(). R=verwaest@chromium.org Review URL: https://codereview.chromium.org/260803002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21138 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ic.cc | 27 ++++++++++++++------------- src/ic.h | 2 +- src/objects.cc | 44 +++++++++++++++++++++++++------------------- src/objects.h | 11 ++++++++--- src/runtime.cc | 9 +++------ 5 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/ic.cc b/src/ic.cc index 6ecb462cf7..3897f88450 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1498,7 +1498,8 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, MapHandleList target_receiver_maps; TargetMaps(&target_receiver_maps); if (target_receiver_maps.length() == 0) { - Handle monomorphic_map = ComputeTransitionedMap(receiver, store_mode); + Handle monomorphic_map = + ComputeTransitionedMap(receiver_map, store_mode); store_mode = GetNonTransitioningStoreMode(store_mode); return isolate()->stub_cache()->ComputeKeyedStoreElement( monomorphic_map, strict_mode(), store_mode); @@ -1514,7 +1515,8 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, if (state() == MONOMORPHIC) { Handle transitioned_receiver_map = receiver_map; if (IsTransitionStoreMode(store_mode)) { - transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode); + transitioned_receiver_map = + ComputeTransitionedMap(receiver_map, store_mode); } if ((receiver_map.is_identical_to(previous_receiver_map) && IsTransitionStoreMode(store_mode)) || @@ -1546,7 +1548,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, if (IsTransitionStoreMode(store_mode)) { Handle transitioned_receiver_map = - ComputeTransitionedMap(receiver, store_mode); + ComputeTransitionedMap(receiver_map, store_mode); map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, transitioned_receiver_map); } @@ -1602,36 +1604,35 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, Handle KeyedStoreIC::ComputeTransitionedMap( - Handle receiver, + Handle map, KeyedAccessStoreMode store_mode) { switch (store_mode) { case STORE_TRANSITION_SMI_TO_OBJECT: case STORE_TRANSITION_DOUBLE_TO_OBJECT: case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: - return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); + return Map::TransitionElementsTo(map, FAST_ELEMENTS); case STORE_TRANSITION_SMI_TO_DOUBLE: case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: - return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); + return Map::TransitionElementsTo(map, FAST_DOUBLE_ELEMENTS); case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: - return JSObject::GetElementsTransitionMap(receiver, - FAST_HOLEY_ELEMENTS); + return Map::TransitionElementsTo(map, FAST_HOLEY_ELEMENTS); case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: - return JSObject::GetElementsTransitionMap(receiver, - FAST_HOLEY_DOUBLE_ELEMENTS); + return Map::TransitionElementsTo(map, FAST_HOLEY_DOUBLE_ELEMENTS); case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: - ASSERT(receiver->map()->has_external_array_elements()); + ASSERT(map->has_external_array_elements()); // Fall through case STORE_NO_TRANSITION_HANDLE_COW: case STANDARD_STORE: case STORE_AND_GROW_NO_TRANSITION: - return Handle(receiver->map(), isolate()); + return map; } - return Handle::null(); + UNREACHABLE(); + return MaybeHandle().ToHandleChecked(); } diff --git a/src/ic.h b/src/ic.h index b42b5fa556..895c21e736 100644 --- a/src/ic.h +++ b/src/ic.h @@ -780,7 +780,7 @@ class KeyedStoreIC: public StoreIC { Handle key, Handle value); - Handle ComputeTransitionedMap(Handle receiver, + Handle ComputeTransitionedMap(Handle map, KeyedAccessStoreMode store_mode); friend class IC; diff --git a/src/objects.cc b/src/objects.cc index 6089558f78..178b5fdae5 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3430,19 +3430,18 @@ static Handle AddMissingElementsTransitions(Handle map, } -Handle JSObject::GetElementsTransitionMap(Handle object, - ElementsKind to_kind) { - Isolate* isolate = object->GetIsolate(); - Handle current_map(object->map()); - ElementsKind from_kind = current_map->elements_kind(); - if (from_kind == to_kind) return current_map; +Handle Map::TransitionElementsTo(Handle map, + ElementsKind to_kind) { + ElementsKind from_kind = map->elements_kind(); + if (from_kind == to_kind) return map; + Isolate* isolate = map->GetIsolate(); Context* native_context = isolate->context()->native_context(); Object* maybe_array_maps = native_context->js_array_maps(); if (maybe_array_maps->IsFixedArray()) { DisallowHeapAllocation no_gc; FixedArray* array_maps = FixedArray::cast(maybe_array_maps); - if (array_maps->get(from_kind) == *current_map) { + if (array_maps->get(from_kind) == *map) { Object* maybe_transitioned_map = array_maps->get(to_kind); if (maybe_transitioned_map->IsMap()) { return handle(Map::cast(maybe_transitioned_map)); @@ -3450,23 +3449,22 @@ Handle JSObject::GetElementsTransitionMap(Handle object, } } - return GetElementsTransitionMapSlow(object, to_kind); + return TransitionElementsToSlow(map, to_kind); } -Handle JSObject::GetElementsTransitionMapSlow(Handle object, - ElementsKind to_kind) { - Handle start_map(object->map()); - ElementsKind from_kind = start_map->elements_kind(); +Handle Map::TransitionElementsToSlow(Handle map, + ElementsKind to_kind) { + ElementsKind from_kind = map->elements_kind(); if (from_kind == to_kind) { - return start_map; + return map; } bool allow_store_transition = // Only remember the map transition if there is not an already existing // non-matching element transition. - !start_map->IsUndefined() && !start_map->is_shared() && + !map->IsUndefined() && !map->is_shared() && IsTransitionElementsKind(from_kind); // Only store fast element maps in ascending generality. @@ -3477,10 +3475,10 @@ Handle JSObject::GetElementsTransitionMapSlow(Handle object, } if (!allow_store_transition) { - return Map::CopyAsElementsKind(start_map, to_kind, OMIT_TRANSITION); + return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); } - return Map::AsElementsKind(start_map, to_kind); + return Map::AsElementsKind(map, to_kind); } @@ -3496,6 +3494,13 @@ Handle Map::AsElementsKind(Handle map, ElementsKind kind) { } +Handle JSObject::GetElementsTransitionMap(Handle object, + ElementsKind to_kind) { + Handle map(object->map()); + return Map::TransitionElementsTo(map, to_kind); +} + + void JSObject::LocalLookupRealNamedProperty(Handle name, LookupResult* result) { DisallowHeapAllocation no_gc; @@ -17159,6 +17164,10 @@ Handle JSTypedArray::MaterializeArrayBuffer( ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); + Handle new_map = Map::TransitionElementsTo( + map, + FixedToExternalElementsKind(map->elements_kind())); + Handle buffer = isolate->factory()->NewJSArrayBuffer(); Handle fixed_typed_array( FixedTypedArrayBase::cast(typed_array->elements())); @@ -17171,9 +17180,6 @@ Handle JSTypedArray::MaterializeArrayBuffer( isolate->factory()->NewExternalArray( fixed_typed_array->length(), typed_array->type(), static_cast(buffer->backing_store())); - Handle new_map = JSObject::GetElementsTransitionMap( - typed_array, - FixedToExternalElementsKind(map->elements_kind())); buffer->set_weak_first_view(*typed_array); ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); diff --git a/src/objects.h b/src/objects.h index 34aff97aca..22c0dd909e 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2461,9 +2461,6 @@ class JSObject: public JSReceiver { // map and the ElementsKind set. static Handle GetElementsTransitionMap(Handle object, ElementsKind to_kind); - static Handle GetElementsTransitionMapSlow(Handle object, - ElementsKind elements_kind); - static void TransitionElementsKind(Handle object, ElementsKind to_kind); @@ -6330,6 +6327,11 @@ class Map: public HeapObject { PropertyAttributes attributes, TransitionFlag flag); + // Returns a new map with all transitions dropped from the given map and + // the ElementsKind set. + static Handle TransitionElementsTo(Handle map, + ElementsKind to_kind); + static Handle AsElementsKind(Handle map, ElementsKind kind); static Handle CopyAsElementsKind(Handle map, @@ -6591,6 +6593,9 @@ class Map: public HeapObject { // the descriptor array. inline void NotifyLeafMapLayoutChange(); + static Handle TransitionElementsToSlow(Handle object, + ElementsKind to_kind); + // Zaps the contents of backing data structures. Note that the // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects // holding weak references when incremental marking is used, because it also diff --git a/src/runtime.cc b/src/runtime.cc index 07c7c79d43..e07876b84b 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -10057,12 +10057,9 @@ class ArrayConcatVisitor { Handle array = isolate_->factory()->NewJSArray(0); Handle length = isolate_->factory()->NewNumber(static_cast(index_offset_)); - Handle map; - if (fast_elements_) { - map = JSObject::GetElementsTransitionMap(array, FAST_HOLEY_ELEMENTS); - } else { - map = JSObject::GetElementsTransitionMap(array, DICTIONARY_ELEMENTS); - } + Handle map = JSObject::GetElementsTransitionMap( + array, + fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS); array->set_map(*map); array->set_length(*length); array->set_elements(*storage_);