Skip to content

Commit 57b54b0

Browse files
sstricklcommit-bot@chromium.org
authored andcommitted
[vm] Unify type testing stub testing framework.
In particular, make it so that the type testing stub testing framework can use the same indirect stub call generation as the flow graph compiler. This avoids having to change generation in two places if we later update how indirect calls are generated. Other changes: * Generate a register mask of modified registers instead of a boolean for more precise reporting of what was modified. * Add a STCInternalRegs struct, like TTSInternalRegs, which exposes the registers not preserved by the subtype test cache stubs. * Be more precise in the TypeTestABI about which registers are preserved on successful checks (namely, the inputs provided by AssertAssignable and InstanceOf) and which may not be, and add the TTS and STC internal registers to the non-preserved list. TEST=Ran modified test on trybots for each supported architecture. Cq-Include-Trybots: luci.dart.try:vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try Change-Id: I58711213bc54572ea7f1e6525707fd193a000235 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173721 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
1 parent 739393b commit 57b54b0

19 files changed

+420
-564
lines changed

runtime/vm/compiler/assembler/assembler_x64.cc

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,6 @@ void Assembler::pushq(const Immediate& imm) {
114114
}
115115
}
116116

117-
void Assembler::PushImmediate(const Immediate& imm) {
118-
if (imm.is_int32()) {
119-
pushq(imm);
120-
} else {
121-
LoadImmediate(TMP, imm);
122-
pushq(TMP);
123-
}
124-
}
125-
126117
void Assembler::popq(Register reg) {
127118
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
128119
EmitRegisterREX(reg, REX_NONE);

runtime/vm/compiler/assembler/assembler_x64.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ class Assembler : public AssemblerBase {
304304
void pushq(Register reg);
305305
void pushq(const Address& address) { EmitUnaryL(address, 0xFF, 6); }
306306
void pushq(const Immediate& imm);
307-
void PushImmediate(const Immediate& imm);
307+
void PushImmediate(const Immediate& imm) { pushq(imm); }
308308
void PushImmediate(int64_t value) { PushImmediate(Immediate(value)); }
309309

310310
void popq(Register reg);
@@ -915,6 +915,15 @@ class Assembler : public AssemblerBase {
915915
OperandSize sz = kEightBytes) {
916916
LoadFromOffset(dst, FieldAddress(base, index, scale, payload_offset), sz);
917917
}
918+
void StoreFieldToOffset(Register src,
919+
Register base,
920+
int32_t offset,
921+
OperandSize sz = kEightBytes) {
922+
if (sz != kEightBytes) {
923+
UNIMPLEMENTED();
924+
}
925+
StoreMemoryValue(src, base, offset - kHeapObjectTag);
926+
}
918927
void LoadFromStack(Register dst, intptr_t depth);
919928
void StoreToStack(Register src, intptr_t depth);
920929
void CompareToStack(Register src, intptr_t depth);

runtime/vm/compiler/backend/flow_graph_compiler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2903,7 +2903,7 @@ void FlowGraphCompiler::GenerateTTSCall(TokenPosition token_pos,
29032903
__ GenerateUnRelocatedPcRelativeCall();
29042904
AddPcRelativeTTSCallTypeTarget(dst_type);
29052905
} else {
2906-
GenerateIndirectTTSCall(reg_with_type, sub_type_cache_index);
2906+
GenerateIndirectTTSCall(assembler(), reg_with_type, sub_type_cache_index);
29072907
}
29082908
EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
29092909
}

runtime/vm/compiler/backend/flow_graph_compiler.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,9 @@ class FlowGraphCompiler : public ValueObject {
606606
const String& dst_name,
607607
LocationSummary* locs);
608608

609-
void GenerateIndirectTTSCall(Register reg_with_type,
610-
intptr_t sub_type_cache_index);
609+
static void GenerateIndirectTTSCall(compiler::Assembler* assembler,
610+
Register reg_with_type,
611+
intptr_t sub_type_cache_index);
611612
#endif
612613

613614
void GenerateRuntimeCall(TokenPosition token_pos,

runtime/vm/compiler/backend/flow_graph_compiler_arm.cc

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,25 @@ void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
204204
#undef __
205205
}
206206

207+
#define __ assembler->
208+
// Static methods of FlowGraphCompiler that take an assembler.
209+
210+
void FlowGraphCompiler::GenerateIndirectTTSCall(compiler::Assembler* assembler,
211+
Register reg_to_call,
212+
intptr_t sub_type_cache_index) {
213+
__ LoadField(
214+
TTSInternalRegs::kScratchReg,
215+
compiler::FieldAddress(
216+
reg_to_call,
217+
compiler::target::AbstractType::type_test_stub_entry_point_offset()));
218+
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
219+
sub_type_cache_index);
220+
__ blx(TTSInternalRegs::kScratchReg);
221+
}
222+
223+
#undef __
207224
#define __ assembler()->
225+
// Instance methods of FlowGraphCompiler.
208226

209227
// Fall through if bool_register contains null.
210228
void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
@@ -222,18 +240,6 @@ void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
222240
__ Bind(&fall_through);
223241
}
224242

225-
void FlowGraphCompiler::GenerateIndirectTTSCall(Register reg_to_call,
226-
intptr_t sub_type_cache_index) {
227-
__ LoadField(
228-
R9,
229-
compiler::FieldAddress(
230-
reg_to_call,
231-
compiler::target::AbstractType::type_test_stub_entry_point_offset()));
232-
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
233-
sub_type_cache_index);
234-
__ blx(R9);
235-
}
236-
237243
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
238244
if (is_optimizing()) {
239245
return;

runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,25 @@ void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
197197
#undef __
198198
}
199199

200+
#define __ assembler->
201+
// Static methods of FlowGraphCompiler that take an assembler.
202+
203+
void FlowGraphCompiler::GenerateIndirectTTSCall(compiler::Assembler* assembler,
204+
Register reg_to_call,
205+
intptr_t sub_type_cache_index) {
206+
__ LoadField(
207+
TTSInternalRegs::kScratchReg,
208+
compiler::FieldAddress(
209+
reg_to_call,
210+
compiler::target::AbstractType::type_test_stub_entry_point_offset()));
211+
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
212+
sub_type_cache_index);
213+
__ blr(TTSInternalRegs::kScratchReg);
214+
}
215+
216+
#undef __
200217
#define __ assembler()->
218+
// Instance methods of FlowGraphCompiler.
201219

202220
// Fall through if bool_register contains null.
203221
void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
@@ -213,18 +231,6 @@ void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
213231
__ Bind(&fall_through);
214232
}
215233

216-
void FlowGraphCompiler::GenerateIndirectTTSCall(Register reg_to_call,
217-
intptr_t sub_type_cache_index) {
218-
__ LoadField(
219-
R9,
220-
compiler::FieldAddress(
221-
reg_to_call,
222-
compiler::target::AbstractType::type_test_stub_entry_point_offset()));
223-
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
224-
sub_type_cache_index);
225-
__ blr(R9);
226-
}
227-
228234
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
229235
if (is_optimizing()) {
230236
return;

runtime/vm/compiler/backend/flow_graph_compiler_x64.cc

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,22 @@ void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
199199
#undef __
200200
}
201201

202+
#define __ assembler->
203+
// Static methods of FlowGraphCompiler that take an assembler.
204+
205+
void FlowGraphCompiler::GenerateIndirectTTSCall(compiler::Assembler* assembler,
206+
Register reg_to_call,
207+
intptr_t sub_type_cache_index) {
208+
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
209+
sub_type_cache_index);
210+
__ Call(compiler::FieldAddress(
211+
reg_to_call,
212+
compiler::target::AbstractType::type_test_stub_entry_point_offset()));
213+
}
214+
215+
#undef __
202216
#define __ assembler()->
217+
// Instance methods of FlowGraphCompiler.
203218

204219
// Fall through if bool_register contains null.
205220
void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
@@ -217,15 +232,6 @@ void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
217232
__ Bind(&fall_through);
218233
}
219234

220-
void FlowGraphCompiler::GenerateIndirectTTSCall(Register reg_to_call,
221-
intptr_t sub_type_cache_index) {
222-
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
223-
sub_type_cache_index);
224-
__ Call(compiler::FieldAddress(
225-
reg_to_call,
226-
compiler::target::AbstractType::type_test_stub_entry_point_offset()));
227-
}
228-
229235
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
230236
if (is_optimizing()) {
231237
return;

runtime/vm/compiler/stub_code_compiler_arm.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,7 +2629,7 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
26292629
// used to initialize this register.
26302630
const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheReg;
26312631
const Register kScratchReg = TypeTestABI::kScratchReg;
2632-
const Register kInstanceCidOrFunction = R9;
2632+
26332633
// Registers that are only used for n >= 3 and must be preserved if used.
26342634
Register kInstanceInstantiatorTypeArgumentsReg = kNoRegister;
26352635
// Registers that are only used for n >= 7 and must be preserved if used.
@@ -2674,16 +2674,18 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
26742674

26752675
Label loop, not_closure;
26762676
if (n >= 5) {
2677-
__ LoadClassIdMayBeSmi(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
2677+
__ LoadClassIdMayBeSmi(STCInternalRegs::kInstanceCidOrFunctionReg,
2678+
TypeTestABI::kInstanceReg);
26782679
} else {
2679-
__ LoadClassId(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
2680+
__ LoadClassId(STCInternalRegs::kInstanceCidOrFunctionReg,
2681+
TypeTestABI::kInstanceReg);
26802682
}
2681-
__ CompareImmediate(kInstanceCidOrFunction, kClosureCid);
2683+
__ CompareImmediate(STCInternalRegs::kInstanceCidOrFunctionReg, kClosureCid);
26822684
__ b(&not_closure, NE);
26832685

26842686
// Closure handling.
26852687
{
2686-
__ ldr(kInstanceCidOrFunction,
2688+
__ ldr(STCInternalRegs::kInstanceCidOrFunctionReg,
26872689
FieldAddress(TypeTestABI::kInstanceReg,
26882690
target::Closure::function_offset()));
26892691
if (n >= 3) {
@@ -2709,7 +2711,7 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
27092711
__ Bind(&not_closure);
27102712
if (n >= 3) {
27112713
Label has_no_type_arguments;
2712-
__ LoadClassById(kScratchReg, kInstanceCidOrFunction);
2714+
__ LoadClassById(kScratchReg, STCInternalRegs::kInstanceCidOrFunctionReg);
27132715
__ mov(kInstanceInstantiatorTypeArgumentsReg, Operand(kNullReg));
27142716
__ ldr(
27152717
kScratchReg,
@@ -2729,7 +2731,7 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
27292731
__ PushRegister(kNullReg);
27302732
}
27312733
}
2732-
__ SmiTag(kInstanceCidOrFunction);
2734+
__ SmiTag(STCInternalRegs::kInstanceCidOrFunctionReg);
27332735
}
27342736

27352737
const intptr_t kNoDepth = -1;
@@ -2746,7 +2748,7 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
27462748
target::SubtypeTestCache::kInstanceClassIdOrFunction));
27472749
__ cmp(kScratchReg, Operand(kNullReg));
27482750
__ b(&not_found, EQ);
2749-
__ cmp(kScratchReg, Operand(kInstanceCidOrFunction));
2751+
__ cmp(kScratchReg, Operand(STCInternalRegs::kInstanceCidOrFunctionReg));
27502752
if (n == 1) {
27512753
__ b(&found, EQ);
27522754
} else {

runtime/vm/compiler/stub_code_compiler_arm64.cc

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,10 +2798,6 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
27982798

27992799
const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheReg;
28002800
const Register kScratchReg = TypeTestABI::kScratchReg;
2801-
const Register kInstanceCidOrFunction = R6;
2802-
const Register kInstanceInstantiatorTypeArgumentsReg = R5;
2803-
const Register kInstanceParentFunctionTypeArgumentsReg = R9;
2804-
const Register kInstanceDelayedFunctionTypeArgumentsReg = R10;
28052801

28062802
// All of these must be distinct from TypeTestABI::kSubtypeTestCacheResultReg
28072803
// since it is used for kNullReg as well.
@@ -2819,29 +2815,30 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
28192815

28202816
Label loop, not_closure;
28212817
if (n >= 5) {
2822-
__ LoadClassIdMayBeSmi(kInstanceCidOrFunction,
2818+
__ LoadClassIdMayBeSmi(STCInternalRegs::kInstanceCidOrFunctionReg,
28232819
TypeTestABI::TypeTestABI::kInstanceReg);
28242820
} else {
2825-
__ LoadClassId(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
2821+
__ LoadClassId(STCInternalRegs::kInstanceCidOrFunctionReg,
2822+
TypeTestABI::kInstanceReg);
28262823
}
2827-
__ CompareImmediate(kInstanceCidOrFunction, kClosureCid);
2824+
__ CompareImmediate(STCInternalRegs::kInstanceCidOrFunctionReg, kClosureCid);
28282825
__ b(&not_closure, NE);
28292826

28302827
// Closure handling.
28312828
{
2832-
__ ldr(kInstanceCidOrFunction,
2829+
__ ldr(STCInternalRegs::kInstanceCidOrFunctionReg,
28332830
FieldAddress(TypeTestABI::kInstanceReg,
28342831
target::Closure::function_offset()));
28352832
if (n >= 3) {
28362833
__ ldr(
2837-
kInstanceInstantiatorTypeArgumentsReg,
2834+
STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
28382835
FieldAddress(TypeTestABI::kInstanceReg,
28392836
target::Closure::instantiator_type_arguments_offset()));
28402837
if (n >= 7) {
2841-
__ ldr(kInstanceParentFunctionTypeArgumentsReg,
2838+
__ ldr(STCInternalRegs::kInstanceParentFunctionTypeArgumentsReg,
28422839
FieldAddress(TypeTestABI::kInstanceReg,
28432840
target::Closure::function_type_arguments_offset()));
2844-
__ ldr(kInstanceDelayedFunctionTypeArgumentsReg,
2841+
__ ldr(STCInternalRegs::kInstanceDelayedFunctionTypeArgumentsReg,
28452842
FieldAddress(TypeTestABI::kInstanceReg,
28462843
target::Closure::delayed_type_arguments_offset()));
28472844
}
@@ -2854,8 +2851,8 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
28542851
__ Bind(&not_closure);
28552852
if (n >= 3) {
28562853
Label has_no_type_arguments;
2857-
__ LoadClassById(kScratchReg, kInstanceCidOrFunction);
2858-
__ mov(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
2854+
__ LoadClassById(kScratchReg, STCInternalRegs::kInstanceCidOrFunctionReg);
2855+
__ mov(STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg, kNullReg);
28592856
__ LoadFieldFromOffset(
28602857
kScratchReg, kScratchReg,
28612858
target::Class::host_type_arguments_field_offset_in_words_offset(),
@@ -2864,16 +2861,18 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
28642861
__ b(&has_no_type_arguments, EQ);
28652862
__ add(kScratchReg, TypeTestABI::kInstanceReg,
28662863
Operand(kScratchReg, LSL, 3));
2867-
__ ldr(kInstanceInstantiatorTypeArgumentsReg,
2864+
__ ldr(STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
28682865
FieldAddress(kScratchReg, 0));
28692866
__ Bind(&has_no_type_arguments);
28702867

28712868
if (n >= 7) {
2872-
__ mov(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
2873-
__ mov(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
2869+
__ mov(STCInternalRegs::kInstanceParentFunctionTypeArgumentsReg,
2870+
kNullReg);
2871+
__ mov(STCInternalRegs::kInstanceDelayedFunctionTypeArgumentsReg,
2872+
kNullReg);
28742873
}
28752874
}
2876-
__ SmiTag(kInstanceCidOrFunction);
2875+
__ SmiTag(STCInternalRegs::kInstanceCidOrFunctionReg);
28772876
}
28782877

28792878
Label found, done, next_iteration;
@@ -2886,7 +2885,7 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
28862885
target::SubtypeTestCache::kInstanceClassIdOrFunction));
28872886
__ cmp(kScratchReg, Operand(kNullReg));
28882887
__ b(&done, EQ);
2889-
__ cmp(kScratchReg, Operand(kInstanceCidOrFunction));
2888+
__ cmp(kScratchReg, Operand(STCInternalRegs::kInstanceCidOrFunctionReg));
28902889
if (n == 1) {
28912890
__ b(&found, EQ);
28922891
} else {
@@ -2901,7 +2900,8 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
29012900
Address(kCacheArrayReg,
29022901
target::kWordSize *
29032902
target::SubtypeTestCache::kInstanceTypeArguments));
2904-
__ cmp(kScratchReg, Operand(kInstanceInstantiatorTypeArgumentsReg));
2903+
__ cmp(kScratchReg,
2904+
Operand(STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg));
29052905
if (n == 3) {
29062906
__ b(&found, EQ);
29072907
} else {
@@ -2928,15 +2928,19 @@ static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
29282928
target::kWordSize *
29292929
target::SubtypeTestCache::
29302930
kInstanceParentFunctionTypeArguments));
2931-
__ cmp(kScratchReg, Operand(kInstanceParentFunctionTypeArgumentsReg));
2931+
__ cmp(
2932+
kScratchReg,
2933+
Operand(STCInternalRegs::kInstanceParentFunctionTypeArgumentsReg));
29322934
__ b(&next_iteration, NE);
29332935

29342936
__ ldr(kScratchReg,
29352937
Address(kCacheArrayReg,
29362938
target::kWordSize *
29372939
target::SubtypeTestCache::
29382940
kInstanceDelayedFunctionTypeArguments));
2939-
__ cmp(kScratchReg, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
2941+
__ cmp(
2942+
kScratchReg,
2943+
Operand(STCInternalRegs::kInstanceDelayedFunctionTypeArgumentsReg));
29402944
__ b(&found, EQ);
29412945
}
29422946
}

0 commit comments

Comments
 (0)