[turbofan] Refactor serializer to include receiver as argument

The receiver is now passed around as the first argument in the Hints array.
This allows for Construct bytecodes to not supply it at all.

Bug: v8:7790
Change-Id: Iae57095526dbc52ed12e0f884875ceb07280c371
Reviewed-on: https://chromium-review.googlesource.com/c/1426118
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59021}
This commit is contained in:
Maya Lekova 2019-01-23 09:45:56 +01:00 committed by Commit Bot
parent 92d9b09c0e
commit 5a88e7103c
2 changed files with 47 additions and 60 deletions

View File

@ -56,7 +56,7 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject {
int parameter_count); int parameter_count);
Environment(SerializerForBackgroundCompilation* serializer, Isolate* isolate, Environment(SerializerForBackgroundCompilation* serializer, Isolate* isolate,
int register_count, int parameter_count, Hints receiver, int register_count, int parameter_count,
const HintsVector& arguments); const HintsVector& arguments);
int parameter_count() const { return parameter_count_; } int parameter_count() const { return parameter_count_; }
@ -92,15 +92,11 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject {
const int register_count_; const int register_count_;
const int parameter_count_; const int parameter_count_;
HintsVector environment_hints_; HintsVector environment_hints_;
static const int kReceiverIndex = 0; int register_base() const { return parameter_count_; }
static const int kParameterBase = 1;
int register_base() const { return 1 + parameter_count_; }
int accumulator_index() const { return register_base() + register_count_; } int accumulator_index() const { return register_base() + register_count_; }
int current_context_index() const { return accumulator_index() + 1; } int current_context_index() const { return accumulator_index() + 1; }
int function_closure_index() const { return current_context_index() + 1; } int function_closure_index() const { return current_context_index() + 1; }
int environment_hints_size() const { int environment_hints_size() const { return function_closure_index() + 1; }
return 1 + parameter_count_ + register_count_ + 3;
}
Hints return_value_hints_; Hints return_value_hints_;
}; };
@ -115,18 +111,15 @@ SerializerForBackgroundCompilation::Environment::Environment(
SerializerForBackgroundCompilation::Environment::Environment( SerializerForBackgroundCompilation::Environment::Environment(
SerializerForBackgroundCompilation* serializer, Isolate* isolate, SerializerForBackgroundCompilation* serializer, Isolate* isolate,
int register_count, int parameter_count, Hints receiver, int register_count, int parameter_count, const HintsVector& arguments)
const HintsVector& arguments)
: Environment(serializer->zone(), isolate, register_count, : Environment(serializer->zone(), isolate, register_count,
parameter_count) { parameter_count) {
environment_hints_[kReceiverIndex] = receiver;
size_t param_count = static_cast<size_t>(parameter_count); size_t param_count = static_cast<size_t>(parameter_count);
// Copy the hints for the actually passed arguments, at most up to // Copy the hints for the actually passed arguments, at most up to
// the parameter_count. // the parameter_count.
for (size_t i = 0; i < std::min(arguments.size(), param_count); ++i) { for (size_t i = 0; i < std::min(arguments.size(), param_count); ++i) {
environment_hints_[kParameterBase + i] = arguments[i]; environment_hints_[i] = arguments[i];
} }
Hints undefined_hint(serializer->zone()); Hints undefined_hint(serializer->zone());
@ -134,7 +127,7 @@ SerializerForBackgroundCompilation::Environment::Environment(
serializer->broker()->isolate()->factory()->undefined_value()); serializer->broker()->isolate()->factory()->undefined_value());
// Pad the rest with "undefined". // Pad the rest with "undefined".
for (size_t i = arguments.size(); i < param_count; ++i) { for (size_t i = arguments.size(); i < param_count; ++i) {
environment_hints_[kParameterBase + i] = undefined_hint; environment_hints_[i] = undefined_hint;
} }
} }
@ -145,7 +138,7 @@ int SerializerForBackgroundCompilation::Environment::RegisterToLocalIndex(
if (reg.is_current_context()) return current_context_index(); if (reg.is_current_context()) return current_context_index();
if (reg.is_function_closure()) return function_closure_index(); if (reg.is_function_closure()) return function_closure_index();
if (reg.is_parameter()) { if (reg.is_parameter()) {
return kParameterBase + reg.ToParameterIndex(parameter_count()); return reg.ToParameterIndex(parameter_count());
} else { } else {
return register_base() + reg.index(); return register_base() + reg.index();
} }
@ -166,16 +159,15 @@ SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation( SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
JSHeapBroker* broker, Zone* zone, FunctionBlueprint function, JSHeapBroker* broker, Zone* zone, FunctionBlueprint function,
const Hints& receiver, const HintsVector& arguments) const HintsVector& arguments)
: broker_(broker), : broker_(broker),
zone_(zone), zone_(zone),
shared_(function.shared), shared_(function.shared),
feedback_(function.feedback), feedback_(function.feedback),
environment_( environment_(new (zone) Environment(
new (zone) Environment(this, broker->isolate(), this, broker->isolate(),
shared_->GetBytecodeArray()->register_count(), shared_->GetBytecodeArray()->register_count(),
shared_->GetBytecodeArray()->parameter_count(), shared_->GetBytecodeArray()->parameter_count(), arguments)) {}
receiver, arguments)) {}
Hints SerializerForBackgroundCompilation::Run() { Hints SerializerForBackgroundCompilation::Run() {
SharedFunctionInfoRef shared(broker(), shared_); SharedFunctionInfoRef shared(broker(), shared_);
@ -313,7 +305,8 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
HintsVector parameters(zone()); HintsVector parameters(zone());
ProcessCallOrConstruct(callee, receiver, parameters); parameters.push_back(receiver);
ProcessCallOrConstruct(callee, parameters);
} }
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
@ -327,9 +320,10 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
environment()->register_hints(iterator->GetRegisterOperand(1)); environment()->register_hints(iterator->GetRegisterOperand(1));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
ProcessCallOrConstruct(callee, receiver, parameters); ProcessCallOrConstruct(callee, parameters);
} }
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
@ -345,10 +339,11 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
environment()->register_hints(iterator->GetRegisterOperand(2)); environment()->register_hints(iterator->GetRegisterOperand(2));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
parameters.push_back(arg1); parameters.push_back(arg1);
ProcessCallOrConstruct(callee, receiver, parameters); ProcessCallOrConstruct(callee, parameters);
} }
void SerializerForBackgroundCompilation::VisitCallAnyReceiver( void SerializerForBackgroundCompilation::VisitCallAnyReceiver(
@ -374,8 +369,9 @@ void SerializerForBackgroundCompilation::VisitCallProperty0(
environment()->register_hints(iterator->GetRegisterOperand(1)); environment()->register_hints(iterator->GetRegisterOperand(1));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver);
ProcessCallOrConstruct(callee, receiver, parameters); ProcessCallOrConstruct(callee, parameters);
} }
void SerializerForBackgroundCompilation::VisitCallProperty1( void SerializerForBackgroundCompilation::VisitCallProperty1(
@ -388,9 +384,10 @@ void SerializerForBackgroundCompilation::VisitCallProperty1(
environment()->register_hints(iterator->GetRegisterOperand(2)); environment()->register_hints(iterator->GetRegisterOperand(2));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
ProcessCallOrConstruct(callee, receiver, parameters); ProcessCallOrConstruct(callee, parameters);
} }
void SerializerForBackgroundCompilation::VisitCallProperty2( void SerializerForBackgroundCompilation::VisitCallProperty2(
@ -405,14 +402,15 @@ void SerializerForBackgroundCompilation::VisitCallProperty2(
environment()->register_hints(iterator->GetRegisterOperand(3)); environment()->register_hints(iterator->GetRegisterOperand(3));
HintsVector parameters(zone()); HintsVector parameters(zone());
parameters.push_back(receiver);
parameters.push_back(arg0); parameters.push_back(arg0);
parameters.push_back(arg1); parameters.push_back(arg1);
ProcessCallOrConstruct(callee, receiver, parameters); ProcessCallOrConstruct(callee, parameters);
} }
void SerializerForBackgroundCompilation::ProcessCallOrConstruct( void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
const Hints& callee, const Hints& receiver, const HintsVector& arguments) { const Hints& callee, const HintsVector& arguments) {
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
for (auto hint : callee.constants()) { for (auto hint : callee.constants()) {
@ -427,14 +425,14 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
Handle<FeedbackVector> feedback(function->feedback_vector(), Handle<FeedbackVector> feedback(function->feedback_vector(),
broker()->isolate()); broker()->isolate());
SerializerForBackgroundCompilation child_serializer( SerializerForBackgroundCompilation child_serializer(
broker(), zone(), {shared, feedback}, receiver, arguments); broker(), zone(), {shared, feedback}, arguments);
environment()->accumulator_hints().Add(child_serializer.Run()); environment()->accumulator_hints().Add(child_serializer.Run());
} }
for (auto hint : callee.function_blueprints()) { for (auto hint : callee.function_blueprints()) {
if (!hint.shared->IsInlineable()) continue; if (!hint.shared->IsInlineable()) continue;
SerializerForBackgroundCompilation child_serializer(broker(), zone(), hint, SerializerForBackgroundCompilation child_serializer(broker(), zone(), hint,
receiver, arguments); arguments);
environment()->accumulator_hints().Add(child_serializer.Run()); environment()->accumulator_hints().Add(child_serializer.Run());
} }
} }
@ -445,35 +443,31 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs(
const Hints& callee = const Hints& callee =
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); int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
bool first_reg_is_receiver =
receiver_mode != ConvertReceiverMode::kNullOrUndefined;
int arg_count;
Hints receiver(zone()); Hints receiver(zone());
interpreter::Register first_arg; if (first_reg_is_receiver) {
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
// The receiver is implicit (and undefined), the arguments are in
// consecutive registers.
arg_count = static_cast<int>(reg_count);
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
first_arg = first_reg;
} else {
// The receiver is the first register, followed by the arguments in the // The receiver is the first register, followed by the arguments in the
// consecutive registers. // consecutive registers.
arg_count = static_cast<int>(reg_count) - 1;
receiver.Add(environment()->register_hints(first_reg)); receiver.Add(environment()->register_hints(first_reg));
first_arg = interpreter::Register(first_reg.index() + 1); } else {
// The receiver is implicit (and undefined), the arguments are in
// consecutive registers.
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
} }
HintsVector arguments(zone()); HintsVector arguments(zone());
arguments.push_back(receiver);
// The function arguments are in consecutive registers. int arg_base = BoolToInt(first_reg_is_receiver);
int arg_base = first_arg.index(); for (int i = arg_base; i < reg_count; ++i) {
for (int i = 0; i < arg_count; ++i) { arguments.push_back(environment()->register_hints(
arguments.push_back( interpreter::Register(first_reg.index() + i)));
environment()->register_hints(interpreter::Register(arg_base + i)));
} }
ProcessCallOrConstruct(callee, receiver, arguments); ProcessCallOrConstruct(callee, arguments);
} }
void SerializerForBackgroundCompilation::VisitReturn( void SerializerForBackgroundCompilation::VisitReturn(
@ -490,26 +484,20 @@ void SerializerForBackgroundCompilation::VisitConstruct(
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);
Hints receiver = environment()->register_hints(first_reg);
interpreter::Register first_arg =
interpreter::Register(first_reg.index() + 1);
int arg_count = static_cast<int>(reg_count) - 1;
HintsVector arguments(zone()); HintsVector arguments(zone());
// Push the target of the construct. // Push the target (callee) of the construct.
arguments.push_back(callee); arguments.push_back(callee);
// The function arguments are in consecutive registers. // The function arguments are in consecutive registers.
int arg_base = first_arg.index(); int arg_base = first_reg.index();
for (int i = 0; i < arg_count; ++i) { for (int i = 0; i < static_cast<int>(reg_count); ++i) {
arguments.push_back( arguments.push_back(
environment()->register_hints(interpreter::Register(arg_base + i))); environment()->register_hints(interpreter::Register(arg_base + i)));
} }
// Push the new_target of the construct. // Push the new_target of the construct.
arguments.push_back(environment()->accumulator_hints()); arguments.push_back(environment()->accumulator_hints());
ProcessCallOrConstruct(callee, receiver, arguments); ProcessCallOrConstruct(callee, arguments);
} }
#define DEFINE_SKIPPED_JUMP(name, ...) \ #define DEFINE_SKIPPED_JUMP(name, ...) \

View File

@ -149,7 +149,6 @@ class SerializerForBackgroundCompilation {
private: private:
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone, SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
FunctionBlueprint function, FunctionBlueprint function,
const Hints& receiver,
const HintsVector& arguments); const HintsVector& arguments);
void TraverseBytecode(); void TraverseBytecode();
@ -165,7 +164,7 @@ class SerializerForBackgroundCompilation {
JSHeapBroker* broker() const { return broker_; } JSHeapBroker* broker() const { return broker_; }
Environment* environment() const { return environment_; } Environment* environment() const { return environment_; }
void ProcessCallOrConstruct(const Hints& callee, const Hints& receiver, void ProcessCallOrConstruct(const Hints& callee,
const HintsVector& arguments); const HintsVector& arguments);
void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator, void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator,
ConvertReceiverMode receiver_mode); ConvertReceiverMode receiver_mode);