diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 39e5a9bcc984b6..f21a0b8dd0fd69 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 8 #define V8_MINOR_VERSION 1 #define V8_BUILD_NUMBER 307 -#define V8_PATCH_LEVEL 30 +#define V8_PATCH_LEVEL 31 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/ic/handler-configuration.cc b/deps/v8/src/ic/handler-configuration.cc index 3a57fc8e4f7457..a9bae12482660a 100644 --- a/deps/v8/src/ic/handler-configuration.cc +++ b/deps/v8/src/ic/handler-configuration.cc @@ -200,11 +200,14 @@ KeyedAccessStoreMode StoreHandler::GetKeyedAccessStoreMode( // static Handle StoreHandler::StoreElementTransition( Isolate* isolate, Handle receiver_map, Handle transition, - KeyedAccessStoreMode store_mode) { + KeyedAccessStoreMode store_mode, MaybeHandle prev_validity_cell) { Handle stub = CodeFactory::ElementsTransitionAndStore(isolate, store_mode).code(); - Handle validity_cell = - Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); + Handle validity_cell; + if (!prev_validity_cell.ToHandle(&validity_cell)) { + validity_cell = + Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); + } Handle handler = isolate->factory()->NewStoreHandler(1); handler->set_smi_handler(*stub); handler->set_validity_cell(*validity_cell); diff --git a/deps/v8/src/ic/handler-configuration.h b/deps/v8/src/ic/handler-configuration.h index a0bef4bfcc666b..7f110d17756306 100644 --- a/deps/v8/src/ic/handler-configuration.h +++ b/deps/v8/src/ic/handler-configuration.h @@ -275,10 +275,10 @@ class StoreHandler final : public DataHandler { MaybeObjectHandle maybe_data1 = MaybeObjectHandle(), MaybeObjectHandle maybe_data2 = MaybeObjectHandle()); - static Handle StoreElementTransition(Isolate* isolate, - Handle receiver_map, - Handle transition, - KeyedAccessStoreMode store_mode); + static Handle StoreElementTransition( + Isolate* isolate, Handle receiver_map, Handle transition, + KeyedAccessStoreMode store_mode, + MaybeHandle prev_validity_cell = MaybeHandle()); static Handle StoreProxy(Isolate* isolate, Handle receiver_map, Handle proxy, diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index fcfd5a580365b2..5f6ff322d27132 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -363,9 +363,20 @@ void IC::ConfigureVectorState(Handle name, Handle map, void IC::ConfigureVectorState(Handle name, MapHandles const& maps, MaybeObjectHandles* handlers) { DCHECK(!IsGlobalIC()); + std::vector maps_and_handlers; + DCHECK_EQ(maps.size(), handlers->size()); + for (size_t i = 0; i < maps.size(); i++) { + maps_and_handlers.push_back(MapAndHandler(maps[i], handlers->at(i))); + } + ConfigureVectorState(name, maps_and_handlers); +} + +void IC::ConfigureVectorState( + Handle name, std::vector const& maps_and_handlers) { + DCHECK(!IsGlobalIC()); // Non-keyed ICs don't track the name explicitly. if (!is_keyed()) name = Handle::null(); - nexus()->ConfigurePolymorphic(name, maps, handlers); + nexus()->ConfigurePolymorphic(name, maps_and_handlers); OnFeedbackChanged("Polymorphic"); } @@ -521,6 +532,22 @@ static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps, return true; } +static bool AddOneReceiverMapIfMissing( + std::vector* receiver_maps_and_handlers, + Handle new_receiver_map) { + DCHECK(!new_receiver_map.is_null()); + if (new_receiver_map->is_deprecated()) return false; + for (MapAndHandler map_and_handler : *receiver_maps_and_handlers) { + Handle map = map_and_handler.first; + if (!map.is_null() && map.is_identical_to(new_receiver_map)) { + return false; + } + } + receiver_maps_and_handlers->push_back( + MapAndHandler(new_receiver_map, MaybeObjectHandle())); + return true; +} + bool IC::UpdatePolymorphicIC(Handle name, const MaybeObjectHandle& handler) { DCHECK(IsHandler(*handler)); @@ -528,16 +555,16 @@ bool IC::UpdatePolymorphicIC(Handle name, if (nexus()->GetName() != *name) return false; } Handle map = receiver_map(); - MapHandles maps; - MaybeObjectHandles handlers; - nexus()->ExtractMapsAndHandlers(&maps, &handlers); - int number_of_maps = static_cast(maps.size()); + std::vector maps_and_handlers; + nexus()->ExtractMapsAndHandlers(&maps_and_handlers); + int number_of_maps = static_cast(maps_and_handlers.size()); int deprecated_maps = 0; int handler_to_overwrite = -1; for (int i = 0; i < number_of_maps; i++) { - Handle current_map = maps.at(i); + Handle current_map = maps_and_handlers.at(i).first; + MaybeObjectHandle current_handler = maps_and_handlers.at(i).second; if (current_map->is_deprecated()) { // Filter out deprecated maps to ensure their instances get migrated. ++deprecated_maps; @@ -547,7 +574,7 @@ bool IC::UpdatePolymorphicIC(Handle name, // in the lattice and need to go MEGAMORPHIC instead. There's one // exception to this rule, which is when we're in RECOMPUTE_HANDLER // state, there we allow to migrate to a new handler. - if (handler.is_identical_to(handlers[i]) && + if (handler.is_identical_to(current_handler) && state() != RECOMPUTE_HANDLER) { return false; } @@ -575,16 +602,16 @@ bool IC::UpdatePolymorphicIC(Handle name, } else { if (is_keyed() && nexus()->GetName() != *name) return false; if (handler_to_overwrite >= 0) { - handlers[handler_to_overwrite] = handler; - if (!map.is_identical_to(maps.at(handler_to_overwrite))) { - maps[handler_to_overwrite] = map; + maps_and_handlers[handler_to_overwrite].second = handler; + if (!map.is_identical_to( + maps_and_handlers.at(handler_to_overwrite).first)) { + maps_and_handlers[handler_to_overwrite].first = map; } } else { - maps.push_back(map); - handlers.push_back(handler); + maps_and_handlers.push_back(MapAndHandler(map, handler)); } - ConfigureVectorState(name, maps, &handlers); + ConfigureVectorState(name, maps_and_handlers); } return true; @@ -597,11 +624,10 @@ void IC::UpdateMonomorphicIC(const MaybeObjectHandle& handler, } void IC::CopyICToMegamorphicCache(Handle name) { - MapHandles maps; - MaybeObjectHandles handlers; - nexus()->ExtractMapsAndHandlers(&maps, &handlers); - for (size_t i = 0; i < maps.size(); ++i) { - UpdateMegamorphicCache(maps.at(i), name, handlers.at(i)); + std::vector maps_and_handlers; + nexus()->ExtractMapsAndHandlers(&maps_and_handlers); + for (const MapAndHandler& map_and_handler : maps_and_handlers) { + UpdateMegamorphicCache(map_and_handler.first, name, map_and_handler.second); } } @@ -1760,9 +1786,9 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, KeyedAccessStoreMode store_mode, Handle new_receiver_map) { - MapHandles target_receiver_maps; - TargetMaps(&target_receiver_maps); - if (target_receiver_maps.empty()) { + std::vector target_maps_and_handlers; + nexus()->ExtractMapsAndHandlers(&target_maps_and_handlers, true); + if (target_maps_and_handlers.empty()) { Handle monomorphic_map = receiver_map; // If we transitioned to a map that is a more general map than incoming // then use the new map. @@ -1773,7 +1799,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, return ConfigureVectorState(Handle(), monomorphic_map, handler); } - for (Handle map : target_receiver_maps) { + for (const MapAndHandler& map_and_handler : target_maps_and_handlers) { + Handle map = map_and_handler.first; if (!map.is_null() && map->instance_type() == JS_PRIMITIVE_WRAPPER_TYPE) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); set_slow_stub_reason("JSPrimitiveWrapper"); @@ -1786,7 +1813,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, // Handle those here if the receiver map hasn't changed or it has transitioned // to a more general kind. KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); - Handle previous_receiver_map = target_receiver_maps.at(0); + Handle previous_receiver_map = target_maps_and_handlers.at(0).first; if (state() == MONOMORPHIC) { Handle transitioned_receiver_map = new_receiver_map; if (IsTransitionOfMonomorphicTarget(*previous_receiver_map, @@ -1815,11 +1842,11 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, DCHECK(state() != GENERIC); bool map_added = - AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); + AddOneReceiverMapIfMissing(&target_maps_and_handlers, receiver_map); if (IsTransitionOfMonomorphicTarget(*receiver_map, *new_receiver_map)) { map_added |= - AddOneReceiverMapIfMissing(&target_receiver_maps, new_receiver_map); + AddOneReceiverMapIfMissing(&target_maps_and_handlers, new_receiver_map); } if (!map_added) { @@ -1831,7 +1858,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, // If the maximum number of receiver maps has been exceeded, use the // megamorphic version of the IC. - if (static_cast(target_receiver_maps.size()) > + if (static_cast(target_maps_and_handlers.size()) > FLAG_max_polymorphic_map_count) { return; } @@ -1852,14 +1879,15 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, // use the megamorphic stub. if (store_mode != STANDARD_STORE) { size_t external_arrays = 0; - for (Handle map : target_receiver_maps) { + for (MapAndHandler map_and_handler : target_maps_and_handlers) { + Handle map = map_and_handler.first; if (map->has_typed_array_elements()) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); external_arrays++; } } if (external_arrays != 0 && - external_arrays != target_receiver_maps.size()) { + external_arrays != target_maps_and_handlers.size()) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); set_slow_stub_reason( "unsupported combination of external and normal arrays"); @@ -1867,21 +1895,21 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, } } - MaybeObjectHandles handlers; - handlers.reserve(target_receiver_maps.size()); - StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode); - if (target_receiver_maps.size() == 0) { + StoreElementPolymorphicHandlers(&target_maps_and_handlers, store_mode); + if (target_maps_and_handlers.size() == 0) { Handle handler = StoreElementHandler(receiver_map, store_mode); ConfigureVectorState(Handle(), receiver_map, handler); - } else if (target_receiver_maps.size() == 1) { - ConfigureVectorState(Handle(), target_receiver_maps[0], handlers[0]); + } else if (target_maps_and_handlers.size() == 1) { + ConfigureVectorState(Handle(), target_maps_and_handlers[0].first, + target_maps_and_handlers[0].second); } else { - ConfigureVectorState(Handle(), target_receiver_maps, &handlers); + ConfigureVectorState(Handle(), target_maps_and_handlers); } } Handle KeyedStoreIC::StoreElementHandler( - Handle receiver_map, KeyedAccessStoreMode store_mode) { + Handle receiver_map, KeyedAccessStoreMode store_mode, + MaybeHandle prev_validity_cell) { DCHECK_IMPLIES( receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()), IsStoreInArrayLiteralICKind(kind())); @@ -1917,8 +1945,11 @@ Handle KeyedStoreIC::StoreElementHandler( } if (IsStoreInArrayLiteralICKind(kind())) return code; - Handle validity_cell = - Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); + Handle validity_cell; + if (!prev_validity_cell.ToHandle(&validity_cell)) { + validity_cell = + Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); + } if (validity_cell->IsSmi()) { // There's no prototype validity cell to check, so we can just use the stub. return code; @@ -1930,16 +1961,17 @@ Handle KeyedStoreIC::StoreElementHandler( } void KeyedStoreIC::StoreElementPolymorphicHandlers( - MapHandles* receiver_maps, MaybeObjectHandles* handlers, + std::vector* receiver_maps_and_handlers, KeyedAccessStoreMode store_mode) { - // Filter out deprecated maps to ensure their instances get migrated. - receiver_maps->erase( - std::remove_if( - receiver_maps->begin(), receiver_maps->end(), - [](const Handle& map) { return map->is_deprecated(); }), - receiver_maps->end()); + std::vector> receiver_maps; + for (size_t i = 0; i < receiver_maps_and_handlers->size(); i++) { + receiver_maps.push_back(receiver_maps_and_handlers->at(i).first); + } - for (Handle receiver_map : *receiver_maps) { + for (size_t i = 0; i < receiver_maps_and_handlers->size(); i++) { + Handle receiver_map = receiver_maps_and_handlers->at(i).first; + DCHECK(!receiver_map->is_deprecated()); + MaybeObjectHandle old_handler = receiver_maps_and_handlers->at(i).second; Handle handler; Handle transition; @@ -1952,8 +1984,8 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( } else { { - Map tmap = receiver_map->FindElementsKindTransitionedMap( - isolate(), *receiver_maps); + Map tmap = receiver_map->FindElementsKindTransitionedMap(isolate(), + receiver_maps); if (!tmap.is_null()) { if (receiver_map->is_stable()) { receiver_map->NotifyLeafMapLayoutChange(isolate()); @@ -1962,6 +1994,16 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( } } + MaybeHandle validity_cell; + HeapObject old_handler_obj; + if (!old_handler.is_null() && + old_handler->GetHeapObject(&old_handler_obj) && + old_handler_obj.IsDataHandler()) { + validity_cell = MaybeHandle( + DataHandler::cast(old_handler_obj).validity_cell(), isolate()); + } + // TODO(mythria): Do not recompute the handler if we know there is no + // change in the handler. // TODO(mvstanton): The code below is doing pessimistic elements // transitions. I would like to stop doing that and rely on Allocation // Site Tracking to do a better job of ensuring the data types are what @@ -1970,14 +2012,15 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( if (!transition.is_null()) { TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_ElementsTransitionAndStoreStub); - handler = StoreHandler::StoreElementTransition(isolate(), receiver_map, - transition, store_mode); + handler = StoreHandler::StoreElementTransition( + isolate(), receiver_map, transition, store_mode, validity_cell); } else { - handler = StoreElementHandler(receiver_map, store_mode); + handler = StoreElementHandler(receiver_map, store_mode, validity_cell); } } DCHECK(!handler.is_null()); - handlers->push_back(MaybeObjectHandle(handler)); + receiver_maps_and_handlers->at(i) = + MapAndHandler(receiver_map, MaybeObjectHandle(handler)); } } diff --git a/deps/v8/src/ic/ic.h b/deps/v8/src/ic/ic.h index 6e17517dcce32c..da4b22a2c27df6 100644 --- a/deps/v8/src/ic/ic.h +++ b/deps/v8/src/ic/ic.h @@ -82,6 +82,8 @@ class IC { // Configure the vector for POLYMORPHIC. void ConfigureVectorState(Handle name, MapHandles const& maps, MaybeObjectHandles* handlers); + void ConfigureVectorState( + Handle name, std::vector const& maps_and_handlers); char TransitionMarkFromState(IC::State state); void TraceIC(const char* type, Handle name); @@ -312,12 +314,13 @@ class KeyedStoreIC : public StoreIC { Handle ComputeTransitionedMap(Handle map, TransitionMode transition_mode); - Handle StoreElementHandler(Handle receiver_map, - KeyedAccessStoreMode store_mode); + Handle StoreElementHandler( + Handle receiver_map, KeyedAccessStoreMode store_mode, + MaybeHandle prev_validity_cell = MaybeHandle()); - void StoreElementPolymorphicHandlers(MapHandles* receiver_maps, - MaybeObjectHandles* handlers, - KeyedAccessStoreMode store_mode); + void StoreElementPolymorphicHandlers( + std::vector* receiver_maps_and_handlers, + KeyedAccessStoreMode store_mode); friend class IC; }; diff --git a/deps/v8/src/objects/feedback-vector.cc b/deps/v8/src/objects/feedback-vector.cc index 732c1e9cd5f786..7028d2b0df4be7 100644 --- a/deps/v8/src/objects/feedback-vector.cc +++ b/deps/v8/src/objects/feedback-vector.cc @@ -899,11 +899,9 @@ void FeedbackNexus::ConfigureMonomorphic(Handle name, } } -void FeedbackNexus::ConfigurePolymorphic(Handle name, - MapHandles const& maps, - MaybeObjectHandles* handlers) { - DCHECK_EQ(handlers->size(), maps.size()); - int receiver_count = static_cast(maps.size()); +void FeedbackNexus::ConfigurePolymorphic( + Handle name, std::vector const& maps_and_handlers) { + int receiver_count = static_cast(maps_and_handlers.size()); DCHECK_GT(receiver_count, 1); Handle array; if (name.is_null()) { @@ -916,10 +914,11 @@ void FeedbackNexus::ConfigurePolymorphic(Handle name, } for (int current = 0; current < receiver_count; ++current) { - Handle map = maps[current]; + Handle map = maps_and_handlers[current].first; array->Set(current * 2, HeapObjectReference::Weak(*map)); - DCHECK(IC::IsHandler(*handlers->at(current))); - array->Set(current * 2 + 1, *handlers->at(current)); + MaybeObjectHandle handler = maps_and_handlers[current].second; + DCHECK(IC::IsHandler(*handler)); + array->Set(current * 2 + 1, *handler); } } @@ -965,11 +964,13 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const { return 0; } -int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, - MaybeObjectHandles* handlers) const { - DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) || - IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) || - IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) || +int FeedbackNexus::ExtractMapsAndHandlers( + std::vector, MaybeObjectHandle>>* maps_and_handlers, + bool drop_deprecated) const { + DCHECK(IsLoadICKind(kind()) || + IsStoreICKind(kind()) | IsKeyedLoadICKind(kind()) || + IsKeyedStoreICKind(kind()) || IsStoreOwnICKind(kind()) || + IsStoreDataPropertyInLiteralKind(kind()) || IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind())); DisallowHeapAllocation no_gc; @@ -990,6 +991,7 @@ int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, } const int increment = 2; HeapObject heap_object; + maps_and_handlers->reserve(array.length() / increment); for (int i = 0; i < array.length(); i += increment) { DCHECK(array.Get(i)->IsWeakOrCleared()); if (array.Get(i)->GetHeapObjectIfWeak(&heap_object)) { @@ -997,8 +999,9 @@ int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, if (!handler->IsCleared()) { DCHECK(IC::IsHandler(handler)); Map map = Map::cast(heap_object); - maps->push_back(handle(map, isolate)); - handlers->push_back(handle(handler, isolate)); + if (drop_deprecated && map.is_deprecated()) continue; + maps_and_handlers->push_back( + MapAndHandler(handle(map, isolate), handle(handler, isolate))); found++; } } @@ -1009,8 +1012,9 @@ int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, if (!handler->IsCleared()) { DCHECK(IC::IsHandler(handler)); Map map = Map::cast(heap_object); - maps->push_back(handle(map, isolate)); - handlers->push_back(handle(handler, isolate)); + if (drop_deprecated && map.is_deprecated()) return 0; + maps_and_handlers->push_back( + MapAndHandler(handle(map, isolate), handle(handler, isolate))); return 1; } } @@ -1082,14 +1086,14 @@ Name FeedbackNexus::GetName() const { KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const { DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedHasICKind(kind())); - MapHandles maps; - MaybeObjectHandles handlers; if (GetKeyType() == PROPERTY) return STANDARD_LOAD; - ExtractMapsAndHandlers(&maps, &handlers); - for (MaybeObjectHandle const& handler : handlers) { - KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler); + std::vector maps_and_handlers; + ExtractMapsAndHandlers(&maps_and_handlers); + for (MapAndHandler map_and_handler : maps_and_handlers) { + KeyedAccessLoadMode mode = + LoadHandler::GetKeyedAccessLoadMode(*map_and_handler.second); if (mode != STANDARD_LOAD) return mode; } @@ -1150,13 +1154,13 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const { DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind())); KeyedAccessStoreMode mode = STANDARD_STORE; - MapHandles maps; - MaybeObjectHandles handlers; if (GetKeyType() == PROPERTY) return mode; - ExtractMapsAndHandlers(&maps, &handlers); - for (const MaybeObjectHandle& maybe_code_handler : handlers) { + std::vector maps_and_handlers; + ExtractMapsAndHandlers(&maps_and_handlers); + for (const MapAndHandler& map_and_handler : maps_and_handlers) { + const MaybeObjectHandle maybe_code_handler = map_and_handler.second; // The first handler that isn't the slow handler will have the bits we need. Handle handler; if (maybe_code_handler.object()->IsStoreHandler()) { diff --git a/deps/v8/src/objects/feedback-vector.h b/deps/v8/src/objects/feedback-vector.h index 207ced2a95b0e8..730f6825f4de2f 100644 --- a/deps/v8/src/objects/feedback-vector.h +++ b/deps/v8/src/objects/feedback-vector.h @@ -59,6 +59,8 @@ enum class FeedbackSlotKind { kKindsNumber // Last value indicating number of kinds. }; +using MapAndHandler = std::pair, MaybeObjectHandle>; + inline bool IsCallICKind(FeedbackSlotKind kind) { return kind == FeedbackSlotKind::kCall; } @@ -647,8 +649,8 @@ class V8_EXPORT_PRIVATE FeedbackNexus final { Map GetFirstMap() const; int ExtractMaps(MapHandles* maps) const; - int ExtractMapsAndHandlers(MapHandles* maps, - MaybeObjectHandles* handlers) const; + int ExtractMapsAndHandlers(std::vector* maps_and_handlers, + bool drop_deprecated = false) const; MaybeObjectHandle FindHandlerForMap(Handle map) const; bool IsCleared() const { @@ -672,8 +674,8 @@ class V8_EXPORT_PRIVATE FeedbackNexus final { void ConfigureMonomorphic(Handle name, Handle receiver_map, const MaybeObjectHandle& handler); - void ConfigurePolymorphic(Handle name, MapHandles const& maps, - MaybeObjectHandles* handlers); + void ConfigurePolymorphic( + Handle name, std::vector const& maps_and_handlers); BinaryOperationHint GetBinaryOperationFeedback() const; CompareOperationHint GetCompareOperationFeedback() const; diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1053939.js b/deps/v8/test/mjsunit/regress/regress-crbug-1053939.js new file mode 100644 index 00000000000000..61ce2e519143ec --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1053939.js @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --no-lazy-feedback-allocation + + +function foo(a, b) { + a[b] = 1; + return a[b]; +} +v = []; +assertEquals(foo(v, 1), 1); +v.__proto__.__proto__ = new Int32Array(); +assertEquals(foo(Object(), 1), 1); +assertEquals(foo(v, 2), undefined);