summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMythri A <mythria@chromium.org>2020-04-02 12:41:52 +0100
committerMichal Klocek <michal.klocek@qt.io>2020-04-24 14:32:11 +0000
commitca5ef7e4a6c5d859d32d6c0628f396b6a1dda295 (patch)
tree5723e5b15bb48ef482ed3796676c8c7cc19c673f
parentbb3309303f4020ab526d9c7889d455793c65ad0c (diff)
downloadqtwebengine-chromium-ca5ef7e4a6c5d859d32d6c0628f396b6a1dda295.tar.gz
[Backport] Security bug 1053939 1/2
Use the existing prototype validity cell when recomputing handlers For keyed stores we recompute handlers based on the receiver maps we have seen. This is done so that we can transition to the most generic elements kind we have seen so far. When we recompute this handlers we get a new prototype validity cell and ignore the existing cell. This leads to incorrect behaviour if the cell was invalid. Recomputing the handler may be extra work which is not worth doing at this point. So we just reuse the existing validity cell and let the IC recompute the handler if we see the map again. Bug: chromium:1053939 Change-Id: I6a7b69317cffe181e3a5c504ef06ff187d2cbf5f Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/v8/src/ic/handler-configuration.cc9
-rw-r--r--chromium/v8/src/ic/handler-configuration.h8
-rw-r--r--chromium/v8/src/ic/ic.cc147
-rw-r--r--chromium/v8/src/ic/ic.h13
-rw-r--r--chromium/v8/src/objects/feedback-vector.cc56
-rw-r--r--chromium/v8/src/objects/feedback-vector.h10
6 files changed, 149 insertions, 94 deletions
diff --git a/chromium/v8/src/ic/handler-configuration.cc b/chromium/v8/src/ic/handler-configuration.cc
index 3a57fc8e4f7..a9bae124826 100644
--- a/chromium/v8/src/ic/handler-configuration.cc
+++ b/chromium/v8/src/ic/handler-configuration.cc
@@ -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);
diff --git a/chromium/v8/src/ic/handler-configuration.h b/chromium/v8/src/ic/handler-configuration.h
index a0bef4bfcc6..7f110d17756 100644
--- a/chromium/v8/src/ic/handler-configuration.h
+++ b/chromium/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<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,
diff --git a/chromium/v8/src/ic/ic.cc b/chromium/v8/src/ic/ic.cc
index f8db4939b82..4d6e3c3bb6d 100644
--- a/chromium/v8/src/ic/ic.cc
+++ b/chromium/v8/src/ic/ic.cc
@@ -377,9 +377,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");
}
@@ -534,6 +545,22 @@ 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));
@@ -541,16 +568,16 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name,
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;
@@ -560,7 +587,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;
}
@@ -588,16 +615,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;
@@ -610,11 +637,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);
}
}
@@ -1772,9 +1798,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.
@@ -1785,7 +1811,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");
@@ -1798,7 +1825,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,
@@ -1827,11 +1854,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) {
@@ -1843,7 +1870,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;
}
@@ -1864,14 +1891,15 @@ 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");
@@ -1879,21 +1907,21 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> 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<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()));
@@ -1929,8 +1957,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;
@@ -1942,16 +1973,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;
@@ -1964,8 +1996,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());
@@ -1974,6 +2006,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
@@ -1982,14 +2024,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/chromium/v8/src/ic/ic.h b/chromium/v8/src/ic/ic.h
index 6e17517dcce..da4b22a2c27 100644
--- a/chromium/v8/src/ic/ic.h
+++ b/chromium/v8/src/ic/ic.h
@@ -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;
};
diff --git a/chromium/v8/src/objects/feedback-vector.cc b/chromium/v8/src/objects/feedback-vector.cc
index 732c1e9cd5f..7028d2b0df4 100644
--- a/chromium/v8/src/objects/feedback-vector.cc
+++ b/chromium/v8/src/objects/feedback-vector.cc
@@ -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,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<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()) {
diff --git a/chromium/v8/src/objects/feedback-vector.h b/chromium/v8/src/objects/feedback-vector.h
index 207ced2a95b..730f6825f4d 100644
--- a/chromium/v8/src/objects/feedback-vector.h
+++ b/chromium/v8/src/objects/feedback-vector.h
@@ -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;