Commit f85e8c47 authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[interpreter,baseline] Make FindNonDefaultConstructor use a RegOutPair

This allows (de)optimizing it in TF.

Bug: v8:13091
Change-Id: Iba64df02379dbf3ac07c96e10facb728e7d10501
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3886869
Auto-Submit: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83113}
parent 415ef632
...@@ -1161,9 +1161,10 @@ void BaselineCompiler::VisitGetSuperConstructor() { ...@@ -1161,9 +1161,10 @@ void BaselineCompiler::VisitGetSuperConstructor() {
} }
void BaselineCompiler::VisitFindNonDefaultConstructor() { void BaselineCompiler::VisitFindNonDefaultConstructor() {
SaveAccumulatorScope accumulator_scope(&basm_);
CallBuiltin<Builtin::kFindNonDefaultConstructor>(RegisterOperand(0), CallBuiltin<Builtin::kFindNonDefaultConstructor>(RegisterOperand(0),
RegisterOperand(1)); RegisterOperand(1));
StoreRegister(2, kReturnRegister1); StoreRegisterPair(2, kReturnRegister0, kReturnRegister1);
} }
namespace { namespace {
......
...@@ -527,10 +527,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::GetSuperConstructor(Register out) { ...@@ -527,10 +527,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::GetSuperConstructor(Register out) {
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::FindNonDefaultConstructor( BytecodeArrayBuilder& BytecodeArrayBuilder::FindNonDefaultConstructor(
Register this_function, Register new_target, Register this_function, Register new_target, RegisterList output) {
Register constructor_or_instance) { OutputFindNonDefaultConstructor(this_function, new_target, output);
OutputFindNonDefaultConstructor(this_function, new_target,
constructor_or_instance);
return *this; return *this;
} }
......
...@@ -386,9 +386,9 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final { ...@@ -386,9 +386,9 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
// throws a TypeError exception. // throws a TypeError exception.
BytecodeArrayBuilder& GetSuperConstructor(Register out); BytecodeArrayBuilder& GetSuperConstructor(Register out);
BytecodeArrayBuilder& FindNonDefaultConstructor( BytecodeArrayBuilder& FindNonDefaultConstructor(Register this_function,
Register this_function, Register new_target, Register new_target,
Register constructor_or_instance); RegisterList output);
// Deletes property from an object. This expects that accumulator contains // Deletes property from an object. This expects that accumulator contains
// the key to be deleted and the register contains a reference to the object. // the key to be deleted and the register contains a reference to the object.
......
...@@ -5791,9 +5791,11 @@ void BytecodeGenerator::BuildSuperCallOptimization( ...@@ -5791,9 +5791,11 @@ void BytecodeGenerator::BuildSuperCallOptimization(
Register this_function, Register new_target, Register this_function, Register new_target,
Register constructor_then_instance, BytecodeLabel* super_ctor_call_done) { Register constructor_then_instance, BytecodeLabel* super_ctor_call_done) {
DCHECK(FLAG_omit_default_ctors); DCHECK(FLAG_omit_default_ctors);
builder()->FindNonDefaultConstructor(this_function, new_target, RegisterList output = register_allocator()->NewRegisterList(2);
constructor_then_instance); builder()->FindNonDefaultConstructor(this_function, new_target, output);
builder()->JumpIfTrue(ToBooleanMode::kAlreadyBoolean, super_ctor_call_done); builder()->MoveRegister(output[1], constructor_then_instance);
builder()->LoadAccumulatorWithRegister(output[0]).JumpIfTrue(
ToBooleanMode::kAlreadyBoolean, super_ctor_call_done);
} }
void BytecodeGenerator::VisitCallNew(CallNew* expr) { void BytecodeGenerator::VisitCallNew(CallNew* expr) {
......
...@@ -228,8 +228,8 @@ namespace interpreter { ...@@ -228,8 +228,8 @@ namespace interpreter {
/* GetSuperConstructor operator */ \ /* GetSuperConstructor operator */ \
V(GetSuperConstructor, ImplicitRegisterUse::kReadAccumulator, \ V(GetSuperConstructor, ImplicitRegisterUse::kReadAccumulator, \
OperandType::kRegOut) \ OperandType::kRegOut) \
V(FindNonDefaultConstructor, ImplicitRegisterUse::kWriteAccumulator, \ V(FindNonDefaultConstructor, ImplicitRegisterUse::kNone, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kRegOut) \ OperandType::kReg, OperandType::kRegOutPair) \
\ \
/* Call operations */ \ /* Call operations */ \
V(CallAnyReceiver, ImplicitRegisterUse::kWriteAccumulator, \ V(CallAnyReceiver, ImplicitRegisterUse::kWriteAccumulator, \
......
...@@ -2781,14 +2781,13 @@ IGNITION_HANDLER(ThrowIfNotSuperConstructor, InterpreterAssembler) { ...@@ -2781,14 +2781,13 @@ IGNITION_HANDLER(ThrowIfNotSuperConstructor, InterpreterAssembler) {
} }
} }
// FinNonDefaultConstructor <this_function> <new_target> // FinNonDefaultConstructor <this_function> <new_target> <output>
// <constructor_or_instance>
// //
// Walks the prototype chain from <this_function>'s super ctor until we see a // Walks the prototype chain from <this_function>'s super ctor until we see a
// non-default ctor. If the walk ends at a default base ctor, creates an // non-default ctor. If the walk ends at a default base ctor, creates an
// instance and stores it in <constructor_or_instance> and stores true into the // instance and stores it in <output[1]> and stores true into output[0].
// accumulator. Otherwise, stores the first non-default ctor into // Otherwise, stores the first non-default ctor into <output[1]> and false into
// <constructor_or_instance> and false into the accumulator. // <output[0]>.
IGNITION_HANDLER(FindNonDefaultConstructor, InterpreterAssembler) { IGNITION_HANDLER(FindNonDefaultConstructor, InterpreterAssembler) {
TNode<Context> context = GetContext(); TNode<Context> context = GetContext();
TVARIABLE(Object, constructor); TVARIABLE(Object, constructor);
...@@ -2806,16 +2805,15 @@ IGNITION_HANDLER(FindNonDefaultConstructor, InterpreterAssembler) { ...@@ -2806,16 +2805,15 @@ IGNITION_HANDLER(FindNonDefaultConstructor, InterpreterAssembler) {
TNode<Object> new_target = LoadRegisterAtOperandIndex(1); TNode<Object> new_target = LoadRegisterAtOperandIndex(1);
TNode<Object> instance = CallBuiltin(Builtin::kFastNewObject, context, TNode<Object> instance = CallBuiltin(Builtin::kFastNewObject, context,
constructor.value(), new_target); constructor.value(), new_target);
StoreRegisterAtOperandIndex(instance, 2);
SetAccumulator(TrueConstant()); StoreRegisterPairAtOperandIndex(TrueConstant(), instance, 2);
Dispatch(); Dispatch();
} }
BIND(&found_something_else); BIND(&found_something_else);
{ {
// Not a base ctor (or bailed out). // Not a base ctor (or bailed out).
StoreRegisterAtOperandIndex(constructor.value(), 2); StoreRegisterPairAtOperandIndex(FalseConstant(), constructor.value(), 2);
SetAccumulator(FalseConstant());
Dispatch(); Dispatch();
} }
} }
......
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