[vm/compiler] Move runtime call out of InstantiateTypeInstr to stub

This simplifies the code and makes it easier for later work
related to lazy-deopt of the instruction when returning from
runtime call.

Issue https://github.com/dart-lang/sdk/issues/45213

TEST=Existing test suite.

Change-Id: I72e72554bdc306a9490a1460927d1dd650bfbe7d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/191040
Reviewed-by: Tess Strickland <sstrickl@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Martin Kustermann 2021-03-17 13:08:01 +00:00 committed by commit-bot@chromium.org
parent 1055db533c
commit 0834f9b7ac
8 changed files with 50 additions and 134 deletions

View file

@ -5422,6 +5422,28 @@ void AssertSubtypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
#endif
}
LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
locs->set_in(0, Location::RegisterLocation(
InstantiateTypeABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiateTypeABI::kFunctionTypeArgumentsReg));
locs->set_out(0,
Location::RegisterLocation(InstantiateTypeABI::kResultTypeReg));
return locs;
}
void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ LoadObject(InstantiateTypeABI::kTypeReg, type());
compiler->GenerateStubCall(source(), StubCode::InstantiateType(),
UntaggedPcDescriptors::kOther, locs(), deopt_id(),
env());
}
LocationSummary* DeoptimizeInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);

View file

@ -3451,42 +3451,6 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(&done);
}
LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
locs->set_in(0, Location::RegisterLocation(
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
locs->set_out(0,
Location::RegisterLocation(InstantiationABI::kResultTypeReg));
return locs;
}
void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Register instantiator_type_args_reg = locs()->in(0).reg();
const Register function_type_args_reg = locs()->in(1).reg();
const Register result_reg = locs()->out(0).reg();
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// A runtime call to instantiate the type is required.
__ PushObject(Object::null_object()); // Make room for the result.
__ PushObject(type());
static_assert(InstantiationABI::kFunctionTypeArgumentsReg <
InstantiationABI::kInstantiatorTypeArgumentsReg,
"Should be ordered to push arguments with one instruction");
__ PushList((1 << instantiator_type_args_reg) |
(1 << function_type_args_reg));
compiler->GenerateRuntimeCall(source(), deopt_id(),
kInstantiateTypeRuntimeEntry, 3, locs());
__ Drop(3); // Drop 2 type vectors, and uninstantiated type.
__ Pop(result_reg); // Pop instantiated type.
}
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {

View file

@ -3019,38 +3019,6 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(&done);
}
LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
locs->set_in(0, Location::RegisterLocation(
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
locs->set_out(0,
Location::RegisterLocation(InstantiationABI::kResultTypeReg));
return locs;
}
void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Register instantiator_type_args_reg = locs()->in(0).reg();
const Register function_type_args_reg = locs()->in(1).reg();
const Register result_reg = locs()->out(0).reg();
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// A runtime call to instantiate the type is required.
__ LoadObject(TMP, type());
__ PushPair(TMP, NULL_REG);
__ PushPair(function_type_args_reg, instantiator_type_args_reg);
compiler->GenerateRuntimeCall(source(), deopt_id(),
kInstantiateTypeRuntimeEntry, 3, locs());
__ Drop(3); // Drop 2 type vectors, and uninstantiated type.
__ Pop(result_reg); // Pop instantiated type.
}
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {

View file

@ -2772,39 +2772,6 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(&done);
}
LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
locs->set_in(0, Location::RegisterLocation(
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
locs->set_out(0,
Location::RegisterLocation(InstantiationABI::kResultTypeReg));
return locs;
}
void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register instantiator_type_args_reg = locs()->in(0).reg();
Register function_type_args_reg = locs()->in(1).reg();
Register result_reg = locs()->out(0).reg();
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// A runtime call to instantiate the type is required.
__ PushObject(Object::null_object()); // Make room for the result.
__ PushObject(type());
__ pushl(instantiator_type_args_reg); // Push instantiator type arguments.
__ pushl(function_type_args_reg); // Push function type arguments.
compiler->GenerateRuntimeCall(source(), deopt_id(),
kInstantiateTypeRuntimeEntry, 3, locs());
__ Drop(3); // Drop 2 type vectors, and uninstantiated type.
__ popl(result_reg); // Pop instantiated type.
}
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {

View file

@ -3108,39 +3108,6 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(&done);
}
LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
locs->set_in(0, Location::RegisterLocation(
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
locs->set_out(0,
Location::RegisterLocation(InstantiationABI::kResultTypeReg));
return locs;
}
void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register instantiator_type_args_reg = locs()->in(0).reg();
Register function_type_args_reg = locs()->in(1).reg();
Register result_reg = locs()->out(0).reg();
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// A runtime call to instantiate the type is required.
__ PushObject(Object::null_object()); // Make room for the result.
__ PushObject(type());
__ pushq(instantiator_type_args_reg); // Push instantiator type arguments.
__ pushq(function_type_args_reg); // Push function type arguments.
compiler->GenerateRuntimeCall(source(), deopt_id(),
kInstantiateTypeRuntimeEntry, 3, locs());
__ Drop(3); // Drop 2 type vectors, and uninstantiated type.
__ popq(result_reg); // Pop instantiated type.
}
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {

View file

@ -204,6 +204,19 @@ void StubCodeCompiler::GenerateAssertAssignableStub(Assembler* assembler) {
#endif
}
void StubCodeCompiler::GenerateInstantiateTypeStub(Assembler* assembler) {
__ EnterStubFrame();
__ PushObject(Object::null_object());
__ PushRegister(InstantiateTypeABI::kTypeReg);
__ PushRegister(InstantiateTypeABI::kInstantiatorTypeArgumentsReg);
__ PushRegister(InstantiateTypeABI::kFunctionTypeArgumentsReg);
__ CallRuntime(kInstantiateTypeRuntimeEntry, /*argument_count=*/3);
__ Drop(3);
__ PopRegister(InstantiateTypeABI::kResultTypeReg);
__ LeaveStubFrame();
__ Ret();
}
void StubCodeCompiler::GenerateInstanceOfStub(Assembler* assembler) {
__ EnterStubFrame();
__ PushObject(NullObject()); // Make room for the result.

View file

@ -19,6 +19,20 @@
namespace dart {
// An architecture independent ABI for the InstantiateType stub.
//
// We re-use registers from another ABI to avoid duplicating this ABI across 4
// architectures.
struct InstantiateTypeABI {
static const Register kTypeReg =
InstantiationABI::kUninstantiatedTypeArgumentsReg;
static const Register kInstantiatorTypeArgumentsReg =
InstantiationABI::kInstantiatorTypeArgumentsReg;
static const Register kFunctionTypeArgumentsReg =
InstantiationABI::kFunctionTypeArgumentsReg;
static const Register kResultTypeReg = InstantiationABI::kResultTypeReg;
};
class RegisterNames {
public:
static const char* RegisterName(Register reg) {

View file

@ -126,6 +126,7 @@ namespace dart {
V(ReThrow) \
V(AssertBoolean) \
V(InstanceOf) \
V(InstantiateType) \
V(InstantiateTypeArguments) \
V(InstantiateTypeArgumentsMayShareInstantiatorTA) \
V(InstantiateTypeArgumentsMayShareFunctionTA) \