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
This commit is contained in:
parent
96517fbed0
commit
5883de41cc
27
src/ic.cc
27
src/ic.cc
@ -1498,7 +1498,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
||||
MapHandleList target_receiver_maps;
|
||||
TargetMaps(&target_receiver_maps);
|
||||
if (target_receiver_maps.length() == 0) {
|
||||
Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
|
||||
Handle<Map> 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<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
||||
if (state() == MONOMORPHIC) {
|
||||
Handle<Map> 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<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
||||
|
||||
if (IsTransitionStoreMode(store_mode)) {
|
||||
Handle<Map> 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<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
||||
|
||||
|
||||
Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
|
||||
Handle<JSObject> receiver,
|
||||
Handle<Map> 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<Map>(receiver->map(), isolate());
|
||||
return map;
|
||||
}
|
||||
return Handle<Map>::null();
|
||||
UNREACHABLE();
|
||||
return MaybeHandle<Map>().ToHandleChecked();
|
||||
}
|
||||
|
||||
|
||||
|
2
src/ic.h
2
src/ic.h
@ -780,7 +780,7 @@ class KeyedStoreIC: public StoreIC {
|
||||
Handle<Object> key,
|
||||
Handle<Object> value);
|
||||
|
||||
Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
|
||||
Handle<Map> ComputeTransitionedMap(Handle<Map> map,
|
||||
KeyedAccessStoreMode store_mode);
|
||||
|
||||
friend class IC;
|
||||
|
@ -3430,19 +3430,18 @@ static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
|
||||
}
|
||||
|
||||
|
||||
Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
|
||||
ElementsKind to_kind) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
Handle<Map> current_map(object->map());
|
||||
ElementsKind from_kind = current_map->elements_kind();
|
||||
if (from_kind == to_kind) return current_map;
|
||||
Handle<Map> Map::TransitionElementsTo(Handle<Map> 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<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
|
||||
}
|
||||
}
|
||||
|
||||
return GetElementsTransitionMapSlow(object, to_kind);
|
||||
return TransitionElementsToSlow(map, to_kind);
|
||||
}
|
||||
|
||||
|
||||
Handle<Map> JSObject::GetElementsTransitionMapSlow(Handle<JSObject> object,
|
||||
ElementsKind to_kind) {
|
||||
Handle<Map> start_map(object->map());
|
||||
ElementsKind from_kind = start_map->elements_kind();
|
||||
Handle<Map> Map::TransitionElementsToSlow(Handle<Map> 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<Map> JSObject::GetElementsTransitionMapSlow(Handle<JSObject> 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> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
|
||||
}
|
||||
|
||||
|
||||
Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
|
||||
ElementsKind to_kind) {
|
||||
Handle<Map> map(object->map());
|
||||
return Map::TransitionElementsTo(map, to_kind);
|
||||
}
|
||||
|
||||
|
||||
void JSObject::LocalLookupRealNamedProperty(Handle<Name> name,
|
||||
LookupResult* result) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
@ -17159,6 +17164,10 @@ Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
|
||||
|
||||
ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind()));
|
||||
|
||||
Handle<Map> new_map = Map::TransitionElementsTo(
|
||||
map,
|
||||
FixedToExternalElementsKind(map->elements_kind()));
|
||||
|
||||
Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
|
||||
Handle<FixedTypedArrayBase> fixed_typed_array(
|
||||
FixedTypedArrayBase::cast(typed_array->elements()));
|
||||
@ -17171,9 +17180,6 @@ Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
|
||||
isolate->factory()->NewExternalArray(
|
||||
fixed_typed_array->length(), typed_array->type(),
|
||||
static_cast<uint8_t*>(buffer->backing_store()));
|
||||
Handle<Map> 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());
|
||||
|
@ -2461,9 +2461,6 @@ class JSObject: public JSReceiver {
|
||||
// map and the ElementsKind set.
|
||||
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
|
||||
ElementsKind to_kind);
|
||||
static Handle<Map> GetElementsTransitionMapSlow(Handle<JSObject> object,
|
||||
ElementsKind elements_kind);
|
||||
|
||||
static void TransitionElementsKind(Handle<JSObject> 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<Map> TransitionElementsTo(Handle<Map> map,
|
||||
ElementsKind to_kind);
|
||||
|
||||
static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
|
||||
|
||||
static Handle<Map> CopyAsElementsKind(Handle<Map> map,
|
||||
@ -6591,6 +6593,9 @@ class Map: public HeapObject {
|
||||
// the descriptor array.
|
||||
inline void NotifyLeafMapLayoutChange();
|
||||
|
||||
static Handle<Map> TransitionElementsToSlow(Handle<Map> 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
|
||||
|
@ -10057,12 +10057,9 @@ class ArrayConcatVisitor {
|
||||
Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
|
||||
Handle<Object> length =
|
||||
isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
|
||||
Handle<Map> map;
|
||||
if (fast_elements_) {
|
||||
map = JSObject::GetElementsTransitionMap(array, FAST_HOLEY_ELEMENTS);
|
||||
} else {
|
||||
map = JSObject::GetElementsTransitionMap(array, DICTIONARY_ELEMENTS);
|
||||
}
|
||||
Handle<Map> map = JSObject::GetElementsTransitionMap(
|
||||
array,
|
||||
fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
|
||||
array->set_map(*map);
|
||||
array->set_length(*length);
|
||||
array->set_elements(*storage_);
|
||||
|
Loading…
Reference in New Issue
Block a user