Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: patch V8 to 8.1.307.31 #33080

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deps/v8/include/v8-version.h
Original file line number Diff line number Diff line change
@@ -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.)
9 changes: 6 additions & 3 deletions deps/v8/src/ic/handler-configuration.cc
Original file line number Diff line number Diff line change
@@ -200,11 +200,14 @@ KeyedAccessStoreMode StoreHandler::GetKeyedAccessStoreMode(
// static
Handle<Object> StoreHandler::StoreElementTransition(
Isolate* isolate, Handle<Map> receiver_map, Handle<Map> transition,
KeyedAccessStoreMode store_mode) {
KeyedAccessStoreMode store_mode, MaybeHandle<Object> prev_validity_cell) {
Handle<Code> stub =
CodeFactory::ElementsTransitionAndStore(isolate, store_mode).code();
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
Handle<Object> validity_cell;
if (!prev_validity_cell.ToHandle(&validity_cell)) {
validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
}
Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(1);
handler->set_smi_handler(*stub);
handler->set_validity_cell(*validity_cell);
8 changes: 4 additions & 4 deletions deps/v8/src/ic/handler-configuration.h
Original file line number Diff line number Diff line change
@@ -275,10 +275,10 @@ class StoreHandler final : public DataHandler {
MaybeObjectHandle maybe_data1 = MaybeObjectHandle(),
MaybeObjectHandle maybe_data2 = MaybeObjectHandle());

static Handle<Object> StoreElementTransition(Isolate* isolate,
Handle<Map> receiver_map,
Handle<Map> transition,
KeyedAccessStoreMode store_mode);
static Handle<Object> StoreElementTransition(
Isolate* isolate, Handle<Map> receiver_map, Handle<Map> transition,
KeyedAccessStoreMode store_mode,
MaybeHandle<Object> prev_validity_cell = MaybeHandle<Object>());

static Handle<Object> StoreProxy(Isolate* isolate, Handle<Map> receiver_map,
Handle<JSProxy> proxy,
147 changes: 95 additions & 52 deletions deps/v8/src/ic/ic.cc
Original file line number Diff line number Diff line change
@@ -363,9 +363,20 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
void IC::ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
MaybeObjectHandles* handlers) {
DCHECK(!IsGlobalIC());
std::vector<MapAndHandler> 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> name, std::vector<MapAndHandler> const& maps_and_handlers) {
DCHECK(!IsGlobalIC());
// Non-keyed ICs don't track the name explicitly.
if (!is_keyed()) name = Handle<Name>::null();
nexus()->ConfigurePolymorphic(name, maps, handlers);
nexus()->ConfigurePolymorphic(name, maps_and_handlers);

OnFeedbackChanged("Polymorphic");
}
@@ -521,23 +532,39 @@ static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps,
return true;
}

static bool AddOneReceiverMapIfMissing(
std::vector<MapAndHandler>* receiver_maps_and_handlers,
Handle<Map> 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 = 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> name,
const MaybeObjectHandle& handler) {
DCHECK(IsHandler(*handler));
if (is_keyed() && state() != RECOMPUTE_HANDLER) {
if (nexus()->GetName() != *name) return false;
}
Handle<Map> map = receiver_map();
MapHandles maps;
MaybeObjectHandles handlers;

nexus()->ExtractMapsAndHandlers(&maps, &handlers);
int number_of_maps = static_cast<int>(maps.size());
std::vector<MapAndHandler> maps_and_handlers;
nexus()->ExtractMapsAndHandlers(&maps_and_handlers);
int number_of_maps = static_cast<int>(maps_and_handlers.size());
int deprecated_maps = 0;
int handler_to_overwrite = -1;

for (int i = 0; i < number_of_maps; i++) {
Handle<Map> current_map = maps.at(i);
Handle<Map> 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> 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> 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> 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<MapAndHandler> 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<Map> receiver_map,
KeyedAccessStoreMode store_mode,
Handle<Map> new_receiver_map) {
MapHandles target_receiver_maps;
TargetMaps(&target_receiver_maps);
if (target_receiver_maps.empty()) {
std::vector<MapAndHandler> target_maps_and_handlers;
nexus()->ExtractMapsAndHandlers(&target_maps_and_handlers, true);
if (target_maps_and_handlers.empty()) {
Handle<Map> 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<Map> receiver_map,
return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler);
}

for (Handle<Map> map : target_receiver_maps) {
for (const MapAndHandler& map_and_handler : target_maps_and_handlers) {
Handle<Map> 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<Map> 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<Map> previous_receiver_map = target_receiver_maps.at(0);
Handle<Map> previous_receiver_map = target_maps_and_handlers.at(0).first;
if (state() == MONOMORPHIC) {
Handle<Map> transitioned_receiver_map = new_receiver_map;
if (IsTransitionOfMonomorphicTarget(*previous_receiver_map,
@@ -1815,11 +1842,11 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> 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<Map> receiver_map,

// If the maximum number of receiver maps has been exceeded, use the
// megamorphic version of the IC.
if (static_cast<int>(target_receiver_maps.size()) >
if (static_cast<int>(target_maps_and_handlers.size()) >
FLAG_max_polymorphic_map_count) {
return;
}
@@ -1852,36 +1879,37 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
// use the megamorphic stub.
if (store_mode != STANDARD_STORE) {
size_t external_arrays = 0;
for (Handle<Map> map : target_receiver_maps) {
for (MapAndHandler map_and_handler : target_maps_and_handlers) {
Handle<Map> 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");
return;
}
}

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<Object> handler = StoreElementHandler(receiver_map, store_mode);
ConfigureVectorState(Handle<Name>(), receiver_map, handler);
} else if (target_receiver_maps.size() == 1) {
ConfigureVectorState(Handle<Name>(), target_receiver_maps[0], handlers[0]);
} else if (target_maps_and_handlers.size() == 1) {
ConfigureVectorState(Handle<Name>(), target_maps_and_handlers[0].first,
target_maps_and_handlers[0].second);
} else {
ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>(), target_maps_and_handlers);
}
}

Handle<Object> KeyedStoreIC::StoreElementHandler(
Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
Handle<Map> receiver_map, KeyedAccessStoreMode store_mode,
MaybeHandle<Object> prev_validity_cell) {
DCHECK_IMPLIES(
receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()),
IsStoreInArrayLiteralICKind(kind()));
@@ -1917,8 +1945,11 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
}

if (IsStoreInArrayLiteralICKind(kind())) return code;
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
Handle<Object> 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<Object> KeyedStoreIC::StoreElementHandler(
}

void KeyedStoreIC::StoreElementPolymorphicHandlers(
MapHandles* receiver_maps, MaybeObjectHandles* handlers,
std::vector<MapAndHandler>* 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>& map) { return map->is_deprecated(); }),
receiver_maps->end());
std::vector<Handle<Map>> 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<Map> receiver_map : *receiver_maps) {
for (size_t i = 0; i < receiver_maps_and_handlers->size(); i++) {
Handle<Map> 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<Object> handler;
Handle<Map> 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<Object> validity_cell;
HeapObject old_handler_obj;
if (!old_handler.is_null() &&
old_handler->GetHeapObject(&old_handler_obj) &&
old_handler_obj.IsDataHandler()) {
validity_cell = MaybeHandle<Object>(
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));
}
}

13 changes: 8 additions & 5 deletions deps/v8/src/ic/ic.h
Original file line number Diff line number Diff line change
@@ -82,6 +82,8 @@ class IC {
// Configure the vector for POLYMORPHIC.
void ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
MaybeObjectHandles* handlers);
void ConfigureVectorState(
Handle<Name> name, std::vector<MapAndHandler> const& maps_and_handlers);

char TransitionMarkFromState(IC::State state);
void TraceIC(const char* type, Handle<Object> name);
@@ -312,12 +314,13 @@ class KeyedStoreIC : public StoreIC {
Handle<Map> ComputeTransitionedMap(Handle<Map> map,
TransitionMode transition_mode);

Handle<Object> StoreElementHandler(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode);
Handle<Object> StoreElementHandler(
Handle<Map> receiver_map, KeyedAccessStoreMode store_mode,
MaybeHandle<Object> prev_validity_cell = MaybeHandle<Object>());

void StoreElementPolymorphicHandlers(MapHandles* receiver_maps,
MaybeObjectHandles* handlers,
KeyedAccessStoreMode store_mode);
void StoreElementPolymorphicHandlers(
std::vector<MapAndHandler>* receiver_maps_and_handlers,
KeyedAccessStoreMode store_mode);

friend class IC;
};
56 changes: 30 additions & 26 deletions deps/v8/src/objects/feedback-vector.cc
Original file line number Diff line number Diff line change
@@ -899,11 +899,9 @@ void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
}
}

void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandles const& maps,
MaybeObjectHandles* handlers) {
DCHECK_EQ(handlers->size(), maps.size());
int receiver_count = static_cast<int>(maps.size());
void FeedbackNexus::ConfigurePolymorphic(
Handle<Name> name, std::vector<MapAndHandler> const& maps_and_handlers) {
int receiver_count = static_cast<int>(maps_and_handlers.size());
DCHECK_GT(receiver_count, 1);
Handle<WeakFixedArray> array;
if (name.is_null()) {
@@ -916,10 +914,11 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
}

for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = maps[current];
Handle<Map> 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<std::pair<Handle<Map>, 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,15 +991,17 @@ 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)) {
MaybeObject handler = array.Get(i + 1);
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<MapAndHandler> 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<MapAndHandler> 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<Code> handler;
if (maybe_code_handler.object()->IsStoreHandler()) {
10 changes: 6 additions & 4 deletions deps/v8/src/objects/feedback-vector.h
Original file line number Diff line number Diff line change
@@ -59,6 +59,8 @@ enum class FeedbackSlotKind {
kKindsNumber // Last value indicating number of kinds.
};

using MapAndHandler = std::pair<Handle<Map>, 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<MapAndHandler>* maps_and_handlers,
bool drop_deprecated = false) const;
MaybeObjectHandle FindHandlerForMap(Handle<Map> map) const;

bool IsCleared() const {
@@ -672,8 +674,8 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
const MaybeObjectHandle& handler);

void ConfigurePolymorphic(Handle<Name> name, MapHandles const& maps,
MaybeObjectHandles* handlers);
void ConfigurePolymorphic(
Handle<Name> name, std::vector<MapAndHandler> const& maps_and_handlers);

BinaryOperationHint GetBinaryOperationFeedback() const;
CompareOperationHint GetCompareOperationFeedback() const;
16 changes: 16 additions & 0 deletions deps/v8/test/mjsunit/regress/regress-crbug-1053939.js
Original file line number Diff line number Diff line change
@@ -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);