Commit 6443a79f authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[ic] Optimize IC::UpdatePolymorphicIC

Instead of iterating over the pair of map and handlers twice -- once
to extract them into a vector, second to process them from the vector
-- combine the two passes into one.

Bug: v8:10582
Change-Id: I4c238b494789ae270798f33302b94b1ec02c7fc8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2400338Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69991}
parent 8b60d8fc
......@@ -11,6 +11,7 @@
#include "src/base/logging.h"
#include "src/builtins/accessors.h"
#include "src/codegen/code-factory.h"
#include "src/common/assert-scope.h"
#include "src/execution/arguments-inl.h"
#include "src/execution/execution.h"
#include "src/execution/frames-inl.h"
......@@ -572,37 +573,48 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name,
Handle<Map> map = receiver_map();
std::vector<MapAndHandler> maps_and_handlers;
nexus()->ExtractMapsAndHandlers(&maps_and_handlers);
int number_of_maps = static_cast<int>(maps_and_handlers.size());
maps_and_handlers.reserve(FLAG_max_valid_polymorphic_map_count);
int deprecated_maps = 0;
int handler_to_overwrite = -1;
for (int i = 0; i < number_of_maps; 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()) {
{
DisallowHeapAllocation no_gc;
int i = 0;
for (FeedbackIterator it(nexus()); !it.done(); it.Advance()) {
if (it.handler()->IsCleared()) continue;
MaybeObjectHandle existing_handler = handle(it.handler(), isolate());
Handle<Map> existing_map = handle(it.map(), isolate());
maps_and_handlers.push_back(
MapAndHandler(existing_map, existing_handler));
if (existing_map->is_deprecated()) {
// Filter out deprecated maps to ensure their instances get migrated.
++deprecated_maps;
} else if (map.is_identical_to(current_map)) {
} else if (map.is_identical_to(existing_map)) {
// If both map and handler stayed the same (and the name is also the
// same as checked above, for keyed accesses), we're not progressing
// 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(current_handler) &&
if (handler.is_identical_to(existing_handler) &&
state() != RECOMPUTE_HANDLER) {
return false;
}
// If the receiver type is already in the polymorphic IC, this indicates
// there was a prototoype chain failure. In that case, just overwrite the
// handler.
// there was a prototoype chain failure. In that case, just overwrite
// the handler.
handler_to_overwrite = i;
} else if (handler_to_overwrite == -1 &&
IsTransitionOfMonomorphicTarget(*current_map, *map)) {
IsTransitionOfMonomorphicTarget(*existing_map, *map)) {
handler_to_overwrite = i;
}
i++;
}
}
int number_of_maps = static_cast<int>(maps_and_handlers.size());
int number_of_valid_maps =
number_of_maps - deprecated_maps - (handler_to_overwrite != -1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment