[maglev] Support CreateClosure
Bug: v8:7700 Change-Id: Iacdb0ecd04d7b50d7dd623feb8646c89cc4016ff Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3757884 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Toon Verwaest <verwaest@chromium.org> Auto-Submit: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#81683}
This commit is contained in:
parent
fb945c9185
commit
c906eec72a
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/base/optional.h"
|
||||
#include "src/base/v8-fallthrough.h"
|
||||
#include "src/builtins/builtins-constructor.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/compiler/compilation-dependencies.h"
|
||||
#include "src/compiler/feedback-source.h"
|
||||
@ -1489,7 +1490,25 @@ void MaglevGraphBuilder::VisitCreateObjectLiteral() {
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateEmptyObjectLiteral)
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(CloneObject)
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(GetTemplateObject)
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateClosure)
|
||||
|
||||
void MaglevGraphBuilder::VisitCreateClosure() {
|
||||
compiler::SharedFunctionInfoRef shared_function_info =
|
||||
GetRefOperand<SharedFunctionInfo>(0);
|
||||
compiler::FeedbackCellRef feedback_cell =
|
||||
feedback().GetClosureFeedbackCell(iterator_.GetIndexOperand(1));
|
||||
uint32_t flags = GetFlagOperand(2);
|
||||
|
||||
if (interpreter::CreateClosureFlags::FastNewClosureBit::decode(flags)) {
|
||||
SetAccumulator(AddNewNode<FastCreateClosure>(
|
||||
{GetContext()}, shared_function_info, feedback_cell));
|
||||
} else {
|
||||
bool pretenured =
|
||||
interpreter::CreateClosureFlags::PretenuredBit::decode(flags);
|
||||
SetAccumulator(AddNewNode<CreateClosure>(
|
||||
{GetContext()}, shared_function_info, feedback_cell, pretenured));
|
||||
}
|
||||
}
|
||||
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateBlockContext)
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateCatchContext)
|
||||
|
||||
|
@ -101,6 +101,8 @@ class MaglevGraphVerifier {
|
||||
case Opcode::kCreateObjectLiteral:
|
||||
case Opcode::kCreateShallowObjectLiteral:
|
||||
case Opcode::kCreateFunctionContext:
|
||||
case Opcode::kCreateClosure:
|
||||
case Opcode::kFastCreateClosure:
|
||||
case Opcode::kReturn:
|
||||
DCHECK_EQ(node->input_count(), 1);
|
||||
CheckValueInputIs(node, 0, ValueRepresentation::kTagged);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "src/common/globals.h"
|
||||
#include "src/compiler/backend/instruction.h"
|
||||
#include "src/ic/handler-configuration.h"
|
||||
#include "src/interpreter/bytecode-flags.h"
|
||||
#include "src/maglev/maglev-code-gen-state.h"
|
||||
#include "src/maglev/maglev-compilation-unit.h"
|
||||
#include "src/maglev/maglev-graph-labeller.h"
|
||||
@ -663,6 +664,50 @@ void CreateFunctionContext::PrintParams(
|
||||
os << "(" << *scope_info().object() << ", " << slot_count() << ")";
|
||||
}
|
||||
|
||||
void FastCreateClosure::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kFastNewClosure>::type;
|
||||
static_assert(D::HasContextParameter());
|
||||
UseFixed(context(), D::ContextRegister());
|
||||
DefineAsFixed(vreg_state, this, kReturnRegister0);
|
||||
}
|
||||
void FastCreateClosure::GenerateCode(MaglevCodeGenState* code_gen_state,
|
||||
const ProcessingState& state) {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kFastNewClosure>::type;
|
||||
|
||||
DCHECK_EQ(ToRegister(context()), D::ContextRegister());
|
||||
__ Move(D::GetRegisterParameter(D::kSharedFunctionInfo),
|
||||
shared_function_info().object());
|
||||
__ Move(D::GetRegisterParameter(D::kFeedbackCell), feedback_cell().object());
|
||||
__ CallBuiltin(Builtin::kFastNewClosure);
|
||||
}
|
||||
void FastCreateClosure::PrintParams(std::ostream& os,
|
||||
MaglevGraphLabeller* graph_labeller) const {
|
||||
os << "(" << *shared_function_info().object() << ", "
|
||||
<< feedback_cell().object() << ")";
|
||||
}
|
||||
|
||||
void CreateClosure::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||
UseFixed(context(), kContextRegister);
|
||||
DefineAsFixed(vreg_state, this, kReturnRegister0);
|
||||
}
|
||||
void CreateClosure::GenerateCode(MaglevCodeGenState* code_gen_state,
|
||||
const ProcessingState& state) {
|
||||
Runtime::FunctionId function_id =
|
||||
pretenured() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure;
|
||||
__ Push(shared_function_info().object());
|
||||
__ Push(feedback_cell().object());
|
||||
__ CallRuntime(function_id);
|
||||
}
|
||||
void CreateClosure::PrintParams(std::ostream& os,
|
||||
MaglevGraphLabeller* graph_labeller) const {
|
||||
os << "(" << *shared_function_info().object() << ", "
|
||||
<< feedback_cell().object();
|
||||
if (pretenured()) {
|
||||
os << " [pretenured]";
|
||||
}
|
||||
os << ")";
|
||||
}
|
||||
|
||||
void CheckMaps::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||
UseRegister(receiver_input());
|
||||
set_temporaries_needed(1);
|
||||
|
@ -121,6 +121,8 @@ class CompactInterpreterFrameState;
|
||||
V(CreateObjectLiteral) \
|
||||
V(CreateShallowObjectLiteral) \
|
||||
V(CreateFunctionContext) \
|
||||
V(CreateClosure) \
|
||||
V(FastCreateClosure) \
|
||||
V(InitialValue) \
|
||||
V(LoadTaggedField) \
|
||||
V(LoadDoubleField) \
|
||||
@ -1741,6 +1743,70 @@ class CreateFunctionContext
|
||||
const uint32_t slot_count_;
|
||||
};
|
||||
|
||||
class FastCreateClosure : public FixedInputValueNodeT<1, FastCreateClosure> {
|
||||
using Base = FixedInputValueNodeT<1, FastCreateClosure>;
|
||||
|
||||
public:
|
||||
explicit FastCreateClosure(
|
||||
uint64_t bitfield, compiler::SharedFunctionInfoRef shared_function_info,
|
||||
compiler::FeedbackCellRef feedback_cell)
|
||||
: Base(bitfield),
|
||||
shared_function_info_(shared_function_info),
|
||||
feedback_cell_(feedback_cell) {}
|
||||
|
||||
compiler::SharedFunctionInfoRef shared_function_info() const {
|
||||
return shared_function_info_;
|
||||
}
|
||||
compiler::FeedbackCellRef feedback_cell() const { return feedback_cell_; }
|
||||
|
||||
Input& context() { return input(0); }
|
||||
|
||||
// The implementation currently calls runtime.
|
||||
static constexpr OpProperties kProperties = OpProperties::Call();
|
||||
|
||||
void AllocateVreg(MaglevVregAllocationState*);
|
||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
|
||||
|
||||
private:
|
||||
const compiler::SharedFunctionInfoRef shared_function_info_;
|
||||
const compiler::FeedbackCellRef feedback_cell_;
|
||||
};
|
||||
|
||||
class CreateClosure : public FixedInputValueNodeT<0, CreateClosure> {
|
||||
using Base = FixedInputValueNodeT<0, CreateClosure>;
|
||||
|
||||
public:
|
||||
explicit CreateClosure(uint64_t bitfield,
|
||||
compiler::SharedFunctionInfoRef shared_function_info,
|
||||
compiler::FeedbackCellRef feedback_cell,
|
||||
bool pretenured)
|
||||
: Base(bitfield),
|
||||
shared_function_info_(shared_function_info),
|
||||
feedback_cell_(feedback_cell),
|
||||
pretenured_(pretenured) {}
|
||||
|
||||
compiler::SharedFunctionInfoRef shared_function_info() const {
|
||||
return shared_function_info_;
|
||||
}
|
||||
compiler::FeedbackCellRef feedback_cell() const { return feedback_cell_; }
|
||||
bool pretenured() const { return pretenured_; }
|
||||
|
||||
Input& context() { return input(0); }
|
||||
|
||||
// The implementation currently calls runtime.
|
||||
static constexpr OpProperties kProperties = OpProperties::Call();
|
||||
|
||||
void AllocateVreg(MaglevVregAllocationState*);
|
||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
|
||||
|
||||
private:
|
||||
const compiler::SharedFunctionInfoRef shared_function_info_;
|
||||
const compiler::FeedbackCellRef feedback_cell_;
|
||||
const bool pretenured_;
|
||||
};
|
||||
|
||||
class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
|
||||
using Base = FixedInputNodeT<1, CheckMaps>;
|
||||
|
||||
|
20
test/mjsunit/maglev/inner-function.js
Normal file
20
test/mjsunit/maglev/inner-function.js
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax --maglev --no-stress-opt
|
||||
|
||||
function foo(x) {
|
||||
var inner = function() {
|
||||
return x;
|
||||
}
|
||||
return inner();
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(foo);
|
||||
assertEquals(1, foo(1));
|
||||
assertEquals(2, foo(2));
|
||||
%OptimizeMaglevOnNextCall(foo);
|
||||
assertEquals(1, foo(1));
|
||||
assertEquals(2, foo(2));
|
||||
assertTrue(isMaglevved(foo));
|
Loading…
Reference in New Issue
Block a user