[turbofan] Support new.target in the serializer.
Bug: v8:7790 Change-Id: Ie98cff6f8b1f184c8152952cc3d39e373c93565d Reviewed-on: https://chromium-review.googlesource.com/c/1435943 Commit-Queue: Georg Neis <neis@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Cr-Commit-Position: refs/heads/master@{#59118}
This commit is contained in:
parent
147d05011d
commit
3145505ad3
@ -15,6 +15,9 @@ namespace v8 {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
namespace compiler {
|
namespace compiler {
|
||||||
|
|
||||||
|
using BytecodeArrayIterator = interpreter::BytecodeArrayIterator;
|
||||||
|
using Register = interpreter::Register;
|
||||||
|
|
||||||
CompilationSubject::CompilationSubject(Handle<JSFunction> closure,
|
CompilationSubject::CompilationSubject(Handle<JSFunction> closure,
|
||||||
Isolate* isolate)
|
Isolate* isolate)
|
||||||
: blueprint_{handle(closure->shared(), isolate),
|
: blueprint_{handle(closure->shared(), isolate),
|
||||||
@ -50,38 +53,46 @@ void Hints::Add(const Hints& other) {
|
|||||||
for (auto x : other.function_blueprints()) AddFunctionBlueprint(x);
|
for (auto x : other.function_blueprints()) AddFunctionBlueprint(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Hints::IsEmpty() const {
|
||||||
|
return constants().empty() && maps().empty() && function_blueprints().empty();
|
||||||
|
}
|
||||||
|
|
||||||
void Hints::Clear() {
|
void Hints::Clear() {
|
||||||
constants_.clear();
|
constants_.clear();
|
||||||
maps_.clear();
|
maps_.clear();
|
||||||
function_blueprints_.clear();
|
function_blueprints_.clear();
|
||||||
|
DCHECK(IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
class SerializerForBackgroundCompilation::Environment : public ZoneObject {
|
class SerializerForBackgroundCompilation::Environment : public ZoneObject {
|
||||||
public:
|
public:
|
||||||
Environment(Zone* zone, Isolate* isolate, CompilationSubject function);
|
Environment(Zone* zone, Isolate* isolate, CompilationSubject function);
|
||||||
Environment(Zone* zone, Isolate* isolate, CompilationSubject function,
|
Environment(Zone* zone, Isolate* isolate, CompilationSubject function,
|
||||||
const HintsVector& arguments);
|
base::Optional<Hints> new_target, const HintsVector& arguments);
|
||||||
|
|
||||||
FunctionBlueprint function() const { return function_; }
|
FunctionBlueprint function() const { return function_; }
|
||||||
|
|
||||||
Hints& accumulator_hints() { return environment_hints_[accumulator_index()]; }
|
Hints& accumulator_hints() { return environment_hints_[accumulator_index()]; }
|
||||||
Hints& register_hints(interpreter::Register reg) {
|
Hints& register_hints(Register reg) {
|
||||||
int local_index = RegisterToLocalIndex(reg);
|
int local_index = RegisterToLocalIndex(reg);
|
||||||
DCHECK_LT(local_index, environment_hints_.size());
|
DCHECK_LT(local_index, environment_hints_.size());
|
||||||
return environment_hints_[local_index];
|
return environment_hints_[local_index];
|
||||||
}
|
}
|
||||||
Hints& return_value_hints() { return return_value_hints_; }
|
Hints& return_value_hints() { return return_value_hints_; }
|
||||||
|
|
||||||
void ClearAccumulatorAndRegisterHints() {
|
// Clears all hints except those for the return value and the closure.
|
||||||
for (auto& hints : environment_hints_) hints.Clear();
|
void ClearEphemeralHints() {
|
||||||
|
DCHECK_EQ(environment_hints_.size(), function_closure_index() + 1);
|
||||||
|
for (int i = 0; i < function_closure_index(); ++i) {
|
||||||
|
environment_hints_[i].Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends the hints for the given register range to {dst} (in order).
|
// Appends the hints for the given register range to {dst} (in order).
|
||||||
void ExportRegisterHints(interpreter::Register first, size_t count,
|
void ExportRegisterHints(Register first, size_t count, HintsVector& dst);
|
||||||
HintsVector& dst);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int RegisterToLocalIndex(interpreter::Register reg) const;
|
int RegisterToLocalIndex(Register reg) const;
|
||||||
|
|
||||||
Zone* zone() const { return zone_; }
|
Zone* zone() const { return zone_; }
|
||||||
int parameter_count() const { return parameter_count_; }
|
int parameter_count() const { return parameter_count_; }
|
||||||
@ -126,7 +137,7 @@ SerializerForBackgroundCompilation::Environment::Environment(
|
|||||||
|
|
||||||
SerializerForBackgroundCompilation::Environment::Environment(
|
SerializerForBackgroundCompilation::Environment::Environment(
|
||||||
Zone* zone, Isolate* isolate, CompilationSubject function,
|
Zone* zone, Isolate* isolate, CompilationSubject function,
|
||||||
const HintsVector& arguments)
|
base::Optional<Hints> new_target, const HintsVector& arguments)
|
||||||
: Environment(zone, isolate, function) {
|
: Environment(zone, isolate, function) {
|
||||||
// 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.
|
||||||
@ -141,10 +152,19 @@ SerializerForBackgroundCompilation::Environment::Environment(
|
|||||||
for (size_t i = arguments.size(); i < param_count; ++i) {
|
for (size_t i = arguments.size(); i < param_count; ++i) {
|
||||||
environment_hints_[i] = undefined_hint;
|
environment_hints_[i] = undefined_hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Register new_target_reg = function_.shared->GetBytecodeArray()
|
||||||
|
->incoming_new_target_or_generator_register();
|
||||||
|
if (new_target_reg.is_valid()) {
|
||||||
|
DCHECK(register_hints(new_target_reg).IsEmpty());
|
||||||
|
if (new_target.has_value()) {
|
||||||
|
register_hints(new_target_reg).Add(*new_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SerializerForBackgroundCompilation::Environment::RegisterToLocalIndex(
|
int SerializerForBackgroundCompilation::Environment::RegisterToLocalIndex(
|
||||||
interpreter::Register reg) const {
|
Register reg) const {
|
||||||
// TODO(mslekova): We also want to gather hints for the context.
|
// TODO(mslekova): We also want to gather hints for the context.
|
||||||
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();
|
||||||
@ -166,11 +186,11 @@ SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
|
|||||||
|
|
||||||
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
|
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
|
||||||
JSHeapBroker* broker, Zone* zone, CompilationSubject function,
|
JSHeapBroker* broker, Zone* zone, CompilationSubject function,
|
||||||
const HintsVector& arguments)
|
base::Optional<Hints> new_target, const HintsVector& arguments)
|
||||||
: broker_(broker),
|
: broker_(broker),
|
||||||
zone_(zone),
|
zone_(zone),
|
||||||
environment_(new (zone) Environment(zone, broker_->isolate(), function,
|
environment_(new (zone) Environment(zone, broker_->isolate(), function,
|
||||||
arguments)) {
|
new_target, arguments)) {
|
||||||
Handle<JSFunction> closure;
|
Handle<JSFunction> closure;
|
||||||
if (function.closure().ToHandle(&closure)) {
|
if (function.closure().ToHandle(&closure)) {
|
||||||
JSFunctionRef(broker, closure).Serialize();
|
JSFunctionRef(broker, closure).Serialize();
|
||||||
@ -194,7 +214,7 @@ void SerializerForBackgroundCompilation::TraverseBytecode() {
|
|||||||
BytecodeArrayRef bytecode_array(
|
BytecodeArrayRef bytecode_array(
|
||||||
broker(), handle(environment()->function().shared->GetBytecodeArray(),
|
broker(), handle(environment()->function().shared->GetBytecodeArray(),
|
||||||
broker()->isolate()));
|
broker()->isolate()));
|
||||||
interpreter::BytecodeArrayIterator iterator(bytecode_array.object());
|
BytecodeArrayIterator iterator(bytecode_array.object());
|
||||||
|
|
||||||
for (; !iterator.done(); iterator.Advance()) {
|
for (; !iterator.done(); iterator.Advance()) {
|
||||||
switch (iterator.current_bytecode()) {
|
switch (iterator.current_bytecode()) {
|
||||||
@ -205,7 +225,7 @@ void SerializerForBackgroundCompilation::TraverseBytecode() {
|
|||||||
SUPPORTED_BYTECODE_LIST(DEFINE_BYTECODE_CASE)
|
SUPPORTED_BYTECODE_LIST(DEFINE_BYTECODE_CASE)
|
||||||
#undef DEFINE_BYTECODE_CASE
|
#undef DEFINE_BYTECODE_CASE
|
||||||
default: {
|
default: {
|
||||||
environment()->ClearAccumulatorAndRegisterHints();
|
environment()->ClearEphemeralHints();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,79 +233,79 @@ void SerializerForBackgroundCompilation::TraverseBytecode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitIllegal(
|
void SerializerForBackgroundCompilation::VisitIllegal(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitWide(
|
void SerializerForBackgroundCompilation::VisitWide(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitExtraWide(
|
void SerializerForBackgroundCompilation::VisitExtraWide(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitLdaUndefined(
|
void SerializerForBackgroundCompilation::VisitLdaUndefined(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
environment()->accumulator_hints().AddConstant(
|
environment()->accumulator_hints().AddConstant(
|
||||||
broker()->isolate()->factory()->undefined_value());
|
broker()->isolate()->factory()->undefined_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitLdaNull(
|
void SerializerForBackgroundCompilation::VisitLdaNull(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
environment()->accumulator_hints().AddConstant(
|
environment()->accumulator_hints().AddConstant(
|
||||||
broker()->isolate()->factory()->null_value());
|
broker()->isolate()->factory()->null_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitLdaZero(
|
void SerializerForBackgroundCompilation::VisitLdaZero(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
environment()->accumulator_hints().AddConstant(
|
environment()->accumulator_hints().AddConstant(
|
||||||
handle(Smi::FromInt(0), broker()->isolate()));
|
handle(Smi::FromInt(0), broker()->isolate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitLdaSmi(
|
void SerializerForBackgroundCompilation::VisitLdaSmi(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
environment()->accumulator_hints().AddConstant(handle(
|
environment()->accumulator_hints().AddConstant(handle(
|
||||||
Smi::FromInt(iterator->GetImmediateOperand(0)), broker()->isolate()));
|
Smi::FromInt(iterator->GetImmediateOperand(0)), broker()->isolate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitLdaConstant(
|
void SerializerForBackgroundCompilation::VisitLdaConstant(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
environment()->accumulator_hints().AddConstant(
|
environment()->accumulator_hints().AddConstant(
|
||||||
handle(iterator->GetConstantForIndexOperand(0), broker()->isolate()));
|
handle(iterator->GetConstantForIndexOperand(0), broker()->isolate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitLdar(
|
void SerializerForBackgroundCompilation::VisitLdar(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
environment()->accumulator_hints().Add(
|
environment()->accumulator_hints().Add(
|
||||||
environment()->register_hints(iterator->GetRegisterOperand(0)));
|
environment()->register_hints(iterator->GetRegisterOperand(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitStar(
|
void SerializerForBackgroundCompilation::VisitStar(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
interpreter::Register reg = iterator->GetRegisterOperand(0);
|
Register reg = iterator->GetRegisterOperand(0);
|
||||||
environment()->register_hints(reg).Clear();
|
environment()->register_hints(reg).Clear();
|
||||||
environment()->register_hints(reg).Add(environment()->accumulator_hints());
|
environment()->register_hints(reg).Add(environment()->accumulator_hints());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitMov(
|
void SerializerForBackgroundCompilation::VisitMov(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
interpreter::Register src = iterator->GetRegisterOperand(0);
|
Register src = iterator->GetRegisterOperand(0);
|
||||||
interpreter::Register dst = iterator->GetRegisterOperand(1);
|
Register dst = iterator->GetRegisterOperand(1);
|
||||||
environment()->register_hints(dst).Clear();
|
environment()->register_hints(dst).Clear();
|
||||||
environment()->register_hints(dst).Add(environment()->register_hints(src));
|
environment()->register_hints(dst).Add(environment()->register_hints(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCreateClosure(
|
void SerializerForBackgroundCompilation::VisitCreateClosure(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
Handle<SharedFunctionInfo> shared(
|
Handle<SharedFunctionInfo> shared(
|
||||||
SharedFunctionInfo::cast(iterator->GetConstantForIndexOperand(0)),
|
SharedFunctionInfo::cast(iterator->GetConstantForIndexOperand(0)),
|
||||||
broker()->isolate());
|
broker()->isolate());
|
||||||
@ -303,12 +323,12 @@ void SerializerForBackgroundCompilation::VisitCreateClosure(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver(
|
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
|
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
|
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
Hints receiver(zone());
|
Hints receiver(zone());
|
||||||
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
|
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
|
||||||
|
|
||||||
@ -317,11 +337,11 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
|
|||||||
|
|
||||||
HintsVector parameters(zone());
|
HintsVector parameters(zone());
|
||||||
parameters.push_back(receiver);
|
parameters.push_back(receiver);
|
||||||
ProcessCallOrConstruct(callee, parameters);
|
ProcessCallOrConstruct(callee, base::nullopt, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
|
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
Hints receiver(zone());
|
Hints receiver(zone());
|
||||||
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
|
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
|
||||||
|
|
||||||
@ -334,11 +354,11 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
|
|||||||
parameters.push_back(receiver);
|
parameters.push_back(receiver);
|
||||||
parameters.push_back(arg0);
|
parameters.push_back(arg0);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, parameters);
|
ProcessCallOrConstruct(callee, base::nullopt, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
|
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
Hints receiver(zone());
|
Hints receiver(zone());
|
||||||
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
|
receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
|
||||||
|
|
||||||
@ -354,26 +374,26 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
|
|||||||
parameters.push_back(arg0);
|
parameters.push_back(arg0);
|
||||||
parameters.push_back(arg1);
|
parameters.push_back(arg1);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, parameters);
|
ProcessCallOrConstruct(callee, base::nullopt, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallAnyReceiver(
|
void SerializerForBackgroundCompilation::VisitCallAnyReceiver(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny);
|
ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallNoFeedback(
|
void SerializerForBackgroundCompilation::VisitCallNoFeedback(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
|
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallProperty(
|
void SerializerForBackgroundCompilation::VisitCallProperty(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
|
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallProperty0(
|
void SerializerForBackgroundCompilation::VisitCallProperty0(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
const Hints& callee =
|
const Hints& callee =
|
||||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||||
const Hints& receiver =
|
const Hints& receiver =
|
||||||
@ -382,11 +402,11 @@ void SerializerForBackgroundCompilation::VisitCallProperty0(
|
|||||||
HintsVector parameters(zone());
|
HintsVector parameters(zone());
|
||||||
parameters.push_back(receiver);
|
parameters.push_back(receiver);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, parameters);
|
ProcessCallOrConstruct(callee, base::nullopt, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallProperty1(
|
void SerializerForBackgroundCompilation::VisitCallProperty1(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
const Hints& callee =
|
const Hints& callee =
|
||||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||||
const Hints& receiver =
|
const Hints& receiver =
|
||||||
@ -398,11 +418,11 @@ void SerializerForBackgroundCompilation::VisitCallProperty1(
|
|||||||
parameters.push_back(receiver);
|
parameters.push_back(receiver);
|
||||||
parameters.push_back(arg0);
|
parameters.push_back(arg0);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, parameters);
|
ProcessCallOrConstruct(callee, base::nullopt, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallProperty2(
|
void SerializerForBackgroundCompilation::VisitCallProperty2(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
const Hints& callee =
|
const Hints& callee =
|
||||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||||
const Hints& receiver =
|
const Hints& receiver =
|
||||||
@ -417,17 +437,17 @@ void SerializerForBackgroundCompilation::VisitCallProperty2(
|
|||||||
parameters.push_back(arg0);
|
parameters.push_back(arg0);
|
||||||
parameters.push_back(arg1);
|
parameters.push_back(arg1);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, parameters);
|
ProcessCallOrConstruct(callee, base::nullopt, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitCallWithSpread(
|
void SerializerForBackgroundCompilation::VisitCallWithSpread(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny, true);
|
ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hints SerializerForBackgroundCompilation::RunChildSerializer(
|
Hints SerializerForBackgroundCompilation::RunChildSerializer(
|
||||||
CompilationSubject function, const HintsVector& arguments,
|
CompilationSubject function, base::Optional<Hints> new_target,
|
||||||
bool with_spread) {
|
const HintsVector& arguments, bool with_spread) {
|
||||||
if (with_spread) {
|
if (with_spread) {
|
||||||
DCHECK_LT(0, arguments.size());
|
DCHECK_LT(0, arguments.size());
|
||||||
// Pad the missing arguments in case we were called with spread operator.
|
// Pad the missing arguments in case we were called with spread operator.
|
||||||
@ -442,16 +462,17 @@ Hints SerializerForBackgroundCompilation::RunChildSerializer(
|
|||||||
padded.resize(
|
padded.resize(
|
||||||
function.blueprint().shared->GetBytecodeArray()->parameter_count(),
|
function.blueprint().shared->GetBytecodeArray()->parameter_count(),
|
||||||
Hints(zone()));
|
Hints(zone()));
|
||||||
return RunChildSerializer(function, padded, false);
|
return RunChildSerializer(function, new_target, padded, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializerForBackgroundCompilation child_serializer(broker(), zone(),
|
SerializerForBackgroundCompilation child_serializer(
|
||||||
function, arguments);
|
broker(), zone(), function, new_target, arguments);
|
||||||
return child_serializer.Run();
|
return child_serializer.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
|
void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
|
||||||
const Hints& callee, const HintsVector& arguments, bool with_spread) {
|
const Hints& callee, base::Optional<Hints> new_target,
|
||||||
|
const HintsVector& arguments, bool with_spread) {
|
||||||
environment()->accumulator_hints().Clear();
|
environment()->accumulator_hints().Clear();
|
||||||
|
|
||||||
for (auto hint : callee.constants()) {
|
for (auto hint : callee.constants()) {
|
||||||
@ -461,22 +482,22 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
|
|||||||
if (!function->shared()->IsInlineable()) continue;
|
if (!function->shared()->IsInlineable()) continue;
|
||||||
|
|
||||||
environment()->accumulator_hints().Add(RunChildSerializer(
|
environment()->accumulator_hints().Add(RunChildSerializer(
|
||||||
{function, broker()->isolate()}, arguments, with_spread));
|
{function, broker()->isolate()}, new_target, arguments, with_spread));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto hint : callee.function_blueprints()) {
|
for (auto hint : callee.function_blueprints()) {
|
||||||
if (!hint.shared->IsInlineable()) continue;
|
if (!hint.shared->IsInlineable()) continue;
|
||||||
environment()->accumulator_hints().Add(
|
environment()->accumulator_hints().Add(RunChildSerializer(
|
||||||
RunChildSerializer(CompilationSubject(hint), arguments, with_spread));
|
CompilationSubject(hint), new_target, arguments, with_spread));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::ProcessCallVarArgs(
|
void SerializerForBackgroundCompilation::ProcessCallVarArgs(
|
||||||
interpreter::BytecodeArrayIterator* iterator,
|
BytecodeArrayIterator* iterator, ConvertReceiverMode receiver_mode,
|
||||||
ConvertReceiverMode receiver_mode, bool with_spread) {
|
bool with_spread) {
|
||||||
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);
|
Register first_reg = iterator->GetRegisterOperand(1);
|
||||||
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
|
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
|
||||||
|
|
||||||
HintsVector arguments(zone());
|
HintsVector arguments(zone());
|
||||||
@ -489,65 +510,63 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs(
|
|||||||
}
|
}
|
||||||
environment()->ExportRegisterHints(first_reg, reg_count, arguments);
|
environment()->ExportRegisterHints(first_reg, reg_count, arguments);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, arguments);
|
ProcessCallOrConstruct(callee, base::nullopt, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitReturn(
|
void SerializerForBackgroundCompilation::VisitReturn(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
environment()->return_value_hints().Add(environment()->accumulator_hints());
|
environment()->return_value_hints().Add(environment()->accumulator_hints());
|
||||||
environment()->ClearAccumulatorAndRegisterHints();
|
environment()->ClearEphemeralHints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::Environment::ExportRegisterHints(
|
void SerializerForBackgroundCompilation::Environment::ExportRegisterHints(
|
||||||
interpreter::Register first, size_t count, HintsVector& dst) {
|
Register first, size_t count, HintsVector& dst) {
|
||||||
dst.resize(dst.size() + count, Hints(zone()));
|
dst.resize(dst.size() + count, Hints(zone()));
|
||||||
int reg_base = first.index();
|
int reg_base = first.index();
|
||||||
for (int i = 0; i < static_cast<int>(count); ++i) {
|
for (int i = 0; i < static_cast<int>(count); ++i) {
|
||||||
dst.push_back(register_hints(interpreter::Register(reg_base + i)));
|
dst.push_back(register_hints(Register(reg_base + i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitConstruct(
|
void SerializerForBackgroundCompilation::VisitConstruct(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
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);
|
Register first_reg = iterator->GetRegisterOperand(1);
|
||||||
size_t reg_count = iterator->GetRegisterCountOperand(2);
|
size_t reg_count = iterator->GetRegisterCountOperand(2);
|
||||||
|
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);
|
||||||
|
|
||||||
// TODO(mslekova): Support new.target.
|
ProcessCallOrConstruct(callee, new_target, arguments);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, arguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerForBackgroundCompilation::VisitConstructWithSpread(
|
void SerializerForBackgroundCompilation::VisitConstructWithSpread(
|
||||||
interpreter::BytecodeArrayIterator* iterator) {
|
BytecodeArrayIterator* iterator) {
|
||||||
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);
|
Register first_reg = iterator->GetRegisterOperand(1);
|
||||||
size_t reg_count = iterator->GetRegisterCountOperand(2);
|
size_t reg_count = iterator->GetRegisterCountOperand(2);
|
||||||
|
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);
|
||||||
|
|
||||||
// TODO(mslekova): Support new.target.
|
ProcessCallOrConstruct(callee, new_target, arguments, true);
|
||||||
|
|
||||||
ProcessCallOrConstruct(callee, arguments, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_SKIPPED_JUMP(name, ...) \
|
#define DEFINE_SKIPPED_JUMP(name, ...) \
|
||||||
void SerializerForBackgroundCompilation::Visit##name( \
|
void SerializerForBackgroundCompilation::Visit##name( \
|
||||||
interpreter::BytecodeArrayIterator* iterator) { \
|
BytecodeArrayIterator* iterator) { \
|
||||||
environment()->ClearAccumulatorAndRegisterHints(); \
|
environment()->ClearEphemeralHints(); \
|
||||||
}
|
}
|
||||||
CLEAR_ENVIRONMENT_LIST(DEFINE_SKIPPED_JUMP)
|
CLEAR_ENVIRONMENT_LIST(DEFINE_SKIPPED_JUMP)
|
||||||
#undef DEFINE_SKIPPED_JUMP
|
#undef DEFINE_SKIPPED_JUMP
|
||||||
|
|
||||||
#define DEFINE_CLEAR_ACCUMULATOR(name, ...) \
|
#define DEFINE_CLEAR_ACCUMULATOR(name, ...) \
|
||||||
void SerializerForBackgroundCompilation::Visit##name( \
|
void SerializerForBackgroundCompilation::Visit##name( \
|
||||||
interpreter::BytecodeArrayIterator* iterator) { \
|
BytecodeArrayIterator* iterator) { \
|
||||||
environment()->accumulator_hints().Clear(); \
|
environment()->accumulator_hints().Clear(); \
|
||||||
}
|
}
|
||||||
CLEAR_ACCUMULATOR_LIST(DEFINE_CLEAR_ACCUMULATOR)
|
CLEAR_ACCUMULATOR_LIST(DEFINE_CLEAR_ACCUMULATOR)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
|
#ifndef V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
|
||||||
#define V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
|
#define V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
|
||||||
|
|
||||||
|
#include "src/base/optional.h"
|
||||||
#include "src/handles.h"
|
#include "src/handles.h"
|
||||||
#include "src/maybe-handles.h"
|
#include "src/maybe-handles.h"
|
||||||
#include "src/zone/zone-containers.h"
|
#include "src/zone/zone-containers.h"
|
||||||
@ -143,6 +144,7 @@ class Hints {
|
|||||||
void Add(const Hints& other);
|
void Add(const Hints& other);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
bool IsEmpty() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZoneVector<Handle<Object>> constants_;
|
ZoneVector<Handle<Object>> constants_;
|
||||||
@ -164,6 +166,7 @@ class SerializerForBackgroundCompilation {
|
|||||||
private:
|
private:
|
||||||
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
|
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
|
||||||
CompilationSubject function,
|
CompilationSubject function,
|
||||||
|
base::Optional<Hints> new_target,
|
||||||
const HintsVector& arguments);
|
const HintsVector& arguments);
|
||||||
|
|
||||||
void TraverseBytecode();
|
void TraverseBytecode();
|
||||||
@ -175,13 +178,16 @@ class SerializerForBackgroundCompilation {
|
|||||||
|
|
||||||
class Environment;
|
class Environment;
|
||||||
|
|
||||||
void ProcessCallOrConstruct(const Hints& callee, const HintsVector& arguments,
|
void ProcessCallOrConstruct(const Hints& callee,
|
||||||
|
base::Optional<Hints> new_target,
|
||||||
|
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,
|
||||||
bool with_spread = false);
|
bool with_spread = false);
|
||||||
|
|
||||||
Hints RunChildSerializer(CompilationSubject function,
|
Hints RunChildSerializer(CompilationSubject function,
|
||||||
|
base::Optional<Hints> new_target,
|
||||||
const HintsVector& arguments, bool with_spread);
|
const HintsVector& arguments, bool with_spread);
|
||||||
|
|
||||||
JSHeapBroker* broker() const { return broker_; }
|
JSHeapBroker* broker() const { return broker_; }
|
||||||
|
Loading…
Reference in New Issue
Block a user