Commit f47f1f77 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Make serializer look at call/construct feedback.

Bug: v8:7790
Change-Id: If48109451676b7f028367f8366848a539949c3a8
Reviewed-on: https://chromium-review.googlesource.com/c/1442255
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59176}
parent 368bf36e
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/interpreter/bytecode-array-iterator.h" #include "src/interpreter/bytecode-array-iterator.h"
#include "src/objects/code.h" #include "src/objects/code.h"
#include "src/objects/shared-function-info-inl.h" #include "src/objects/shared-function-info-inl.h"
#include "src/vector-slot-pair.h"
#include "src/zone/zone.h" #include "src/zone/zone.h"
namespace v8 { namespace v8 {
...@@ -333,52 +334,56 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver( ...@@ -333,52 +334,56 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver(
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
Hints receiver(zone());
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
const Hints& callee = const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(1));
Hints receiver(zone());
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver); parameters.push_back(receiver);
ProcessCallOrConstruct(callee, base::nullopt, parameters);
ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
} }
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
Hints receiver(zone());
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
const Hints& callee = const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
const Hints& arg0 = const Hints& arg0 =
environment()->register_hints(iterator->GetRegisterOperand(1)); environment()->register_hints(iterator->GetRegisterOperand(1));
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(2));
Hints receiver(zone());
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver); parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
ProcessCallOrConstruct(callee, base::nullopt, parameters); ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
} }
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
Hints receiver(zone());
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
const Hints& callee = const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
const Hints& arg0 = const Hints& arg0 =
environment()->register_hints(iterator->GetRegisterOperand(1)); environment()->register_hints(iterator->GetRegisterOperand(1));
const Hints& arg1 = const Hints& arg1 =
environment()->register_hints(iterator->GetRegisterOperand(2)); environment()->register_hints(iterator->GetRegisterOperand(2));
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(3));
Hints receiver(zone());
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver); parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
parameters.push_back(arg1); parameters.push_back(arg1);
ProcessCallOrConstruct(callee, base::nullopt, parameters); ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
} }
void SerializerForBackgroundCompilation::VisitCallAnyReceiver( void SerializerForBackgroundCompilation::VisitCallAnyReceiver(
...@@ -402,11 +407,12 @@ void SerializerForBackgroundCompilation::VisitCallProperty0( ...@@ -402,11 +407,12 @@ void SerializerForBackgroundCompilation::VisitCallProperty0(
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
const Hints& receiver = const Hints& receiver =
environment()->register_hints(iterator->GetRegisterOperand(1)); environment()->register_hints(iterator->GetRegisterOperand(1));
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(2));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver); parameters.push_back(receiver);
ProcessCallOrConstruct(callee, base::nullopt, parameters); ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
} }
void SerializerForBackgroundCompilation::VisitCallProperty1( void SerializerForBackgroundCompilation::VisitCallProperty1(
...@@ -417,12 +423,13 @@ void SerializerForBackgroundCompilation::VisitCallProperty1( ...@@ -417,12 +423,13 @@ void SerializerForBackgroundCompilation::VisitCallProperty1(
environment()->register_hints(iterator->GetRegisterOperand(1)); environment()->register_hints(iterator->GetRegisterOperand(1));
const Hints& arg0 = const Hints& arg0 =
environment()->register_hints(iterator->GetRegisterOperand(2)); environment()->register_hints(iterator->GetRegisterOperand(2));
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(3));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver); parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
ProcessCallOrConstruct(callee, base::nullopt, parameters); ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
} }
void SerializerForBackgroundCompilation::VisitCallProperty2( void SerializerForBackgroundCompilation::VisitCallProperty2(
...@@ -435,13 +442,14 @@ void SerializerForBackgroundCompilation::VisitCallProperty2( ...@@ -435,13 +442,14 @@ void SerializerForBackgroundCompilation::VisitCallProperty2(
environment()->register_hints(iterator->GetRegisterOperand(2)); environment()->register_hints(iterator->GetRegisterOperand(2));
const Hints& arg1 = const Hints& arg1 =
environment()->register_hints(iterator->GetRegisterOperand(3)); environment()->register_hints(iterator->GetRegisterOperand(3));
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(4));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver); parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
parameters.push_back(arg1); parameters.push_back(arg1);
ProcessCallOrConstruct(callee, base::nullopt, parameters); ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
} }
void SerializerForBackgroundCompilation::VisitCallWithSpread( void SerializerForBackgroundCompilation::VisitCallWithSpread(
...@@ -474,9 +482,37 @@ Hints SerializerForBackgroundCompilation::RunChildSerializer( ...@@ -474,9 +482,37 @@ Hints SerializerForBackgroundCompilation::RunChildSerializer(
return child_serializer.Run(); return child_serializer.Run();
} }
namespace {
base::Optional<HeapObjectRef> GetHeapObjectFeedback(
JSHeapBroker* broker, Handle<FeedbackVector> feedback_vector,
FeedbackSlot slot) {
if (slot.IsInvalid()) return base::nullopt;
FeedbackNexus nexus(feedback_vector, slot);
VectorSlotPair feedback(feedback_vector, slot, nexus.ic_state());
DCHECK(feedback.IsValid());
if (nexus.IsUninitialized()) return base::nullopt;
HeapObject object;
if (!nexus.GetFeedback()->GetHeapObject(&object)) return base::nullopt;
return HeapObjectRef(broker, handle(object, broker->isolate()));
}
} // namespace
void SerializerForBackgroundCompilation::ProcessCallOrConstruct( void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
const Hints& callee, base::Optional<Hints> new_target, Hints callee, base::Optional<Hints> new_target,
const HintsVector& arguments, bool with_spread) { const HintsVector& arguments, FeedbackSlot slot, bool with_spread) {
// Incorporate feedback into hints.
base::Optional<HeapObjectRef> feedback = GetHeapObjectFeedback(
broker(), environment()->function().feedback_vector, slot);
if (feedback.has_value() && feedback->map().is_callable()) {
if (new_target.has_value()) {
// Construct; feedback is new_target.
new_target->AddConstant(feedback->object());
} else {
// Call; feedback is callee.
callee.AddConstant(feedback->object());
}
}
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
for (auto hint : callee.constants()) { for (auto hint : callee.constants()) {
...@@ -503,6 +539,10 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs( ...@@ -503,6 +539,10 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs(
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1); interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2)); int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
FeedbackSlot slot;
if (iterator->current_bytecode() != interpreter::Bytecode::kCallNoFeedback) {
slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(3));
}
HintsVector arguments(zone()); HintsVector arguments(zone());
// The receiver is either given in the first register or it is implicitly // The receiver is either given in the first register or it is implicitly
...@@ -514,7 +554,7 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs( ...@@ -514,7 +554,7 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs(
} }
environment()->ExportRegisterHints(first_reg, reg_count, arguments); environment()->ExportRegisterHints(first_reg, reg_count, arguments);
ProcessCallOrConstruct(callee, base::nullopt, arguments); ProcessCallOrConstruct(callee, base::nullopt, arguments, slot);
} }
void SerializerForBackgroundCompilation::VisitReturn( void SerializerForBackgroundCompilation::VisitReturn(
...@@ -538,12 +578,13 @@ void SerializerForBackgroundCompilation::VisitConstruct( ...@@ -538,12 +578,13 @@ void SerializerForBackgroundCompilation::VisitConstruct(
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1); interpreter::Register first_reg = iterator->GetRegisterOperand(1);
size_t reg_count = iterator->GetRegisterCountOperand(2); size_t reg_count = iterator->GetRegisterCountOperand(2);
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(3));
const Hints& new_target = environment()->accumulator_hints(); const Hints& new_target = environment()->accumulator_hints();
HintsVector arguments(zone()); HintsVector arguments(zone());
environment()->ExportRegisterHints(first_reg, reg_count, arguments); environment()->ExportRegisterHints(first_reg, reg_count, arguments);
ProcessCallOrConstruct(callee, new_target, arguments); ProcessCallOrConstruct(callee, new_target, arguments, slot);
} }
void SerializerForBackgroundCompilation::VisitConstructWithSpread( void SerializerForBackgroundCompilation::VisitConstructWithSpread(
...@@ -552,12 +593,13 @@ void SerializerForBackgroundCompilation::VisitConstructWithSpread( ...@@ -552,12 +593,13 @@ void SerializerForBackgroundCompilation::VisitConstructWithSpread(
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1); interpreter::Register first_reg = iterator->GetRegisterOperand(1);
size_t reg_count = iterator->GetRegisterCountOperand(2); size_t reg_count = iterator->GetRegisterCountOperand(2);
FeedbackSlot slot = FeedbackVector::ToSlot(iterator->GetIndexOperand(3));
const Hints& new_target = environment()->accumulator_hints(); const Hints& new_target = environment()->accumulator_hints();
HintsVector arguments(zone()); HintsVector arguments(zone());
environment()->ExportRegisterHints(first_reg, reg_count, arguments); environment()->ExportRegisterHints(first_reg, reg_count, arguments);
ProcessCallOrConstruct(callee, new_target, arguments, true); ProcessCallOrConstruct(callee, new_target, arguments, slot, true);
} }
#define DEFINE_SKIPPED_JUMP(name, ...) \ #define DEFINE_SKIPPED_JUMP(name, ...) \
......
...@@ -186,9 +186,8 @@ class SerializerForBackgroundCompilation { ...@@ -186,9 +186,8 @@ class SerializerForBackgroundCompilation {
class Environment; class Environment;
void ProcessCallOrConstruct(const Hints& callee, void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target,
base::Optional<Hints> new_target, const HintsVector& arguments, FeedbackSlot slot,
const HintsVector& arguments,
bool with_spread = false); bool with_spread = false);
void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator, void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator,
ConvertReceiverMode receiver_mode, ConvertReceiverMode receiver_mode,
......
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