Skip to content

Commit f6906f8

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
[vm/compiler] Add type testing stubs to allow TypeParameter types to be called indirectly
Right now AssertAssignable will not call the TTS of a TypeParameter but instead load the value for the type parameter inline and then call it's TTS. To prepare for future changes where we want to call TTS of an arbitrary type object, we need to be able to install a functioning TTS on TypeParameter, which this CL does. Issue #40813 Change-Id: I0792cc1a796fe8afb2167b7665580b3f1385005b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162007 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Tess Strickland <[email protected]>
1 parent 1c7731d commit f6906f8

16 files changed

+321
-20
lines changed

runtime/vm/compiler/relocation.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ CodePtr CodeRelocator::GetTarget(const StaticCallsTableEntry& call) {
434434
// live in the "vm-isolate" - such as `Type::dynamic_type()`).
435435
if (destination_.InVMIsolateHeap()) {
436436
auto object_store = thread_->isolate()->object_store();
437+
437438
if (destination_.raw() == StubCode::DefaultTypeTest().raw()) {
438439
destination_ = object_store->default_tts_stub();
439440
} else if (destination_.raw() ==
@@ -445,6 +446,12 @@ CodePtr CodeRelocator::GetTarget(const StaticCallsTableEntry& call) {
445446
destination_ = object_store->unreachable_tts_stub();
446447
} else if (destination_.raw() == StubCode::SlowTypeTest().raw()) {
447448
destination_ = object_store->slow_tts_stub();
449+
} else if (destination_.raw() ==
450+
StubCode::NullableTypeParameterTypeTest().raw()) {
451+
destination_ = object_store->nullable_type_parameter_tts_stub();
452+
} else if (destination_.raw() ==
453+
StubCode::TypeParameterTypeTest().raw()) {
454+
destination_ = object_store->type_parameter_tts_stub();
448455
} else {
449456
UNREACHABLE();
450457
}

runtime/vm/compiler/runtime_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,8 @@ class TypeParameter : public AllStatic {
883883
public:
884884
static word InstanceSize();
885885
static word NextFieldOffset();
886+
static word parameterized_class_id_offset();
887+
static word index_offset();
886888
};
887889

888890
class LibraryPrefix : public AllStatic {

runtime/vm/compiler/runtime_offsets_extracted.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 24;
378378
static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
379379
static constexpr dart::compiler::target::word Type_type_state_offset = 32;
380380
static constexpr dart::compiler::target::word Type_nullability_offset = 33;
381+
static constexpr dart::compiler::target::word
382+
TypeParameter_parameterized_class_id_offset = 28;
383+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 36;
381384
static constexpr dart::compiler::target::word
382385
TypeArguments_instantiations_offset = 4;
383386
static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -886,6 +889,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 48;
886889
static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
887890
static constexpr dart::compiler::target::word Type_type_state_offset = 60;
888891
static constexpr dart::compiler::target::word Type_nullability_offset = 61;
892+
static constexpr dart::compiler::target::word
893+
TypeParameter_parameterized_class_id_offset = 56;
894+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 64;
889895
static constexpr dart::compiler::target::word
890896
TypeArguments_instantiations_offset = 8;
891897
static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -1390,6 +1396,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 24;
13901396
static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
13911397
static constexpr dart::compiler::target::word Type_type_state_offset = 32;
13921398
static constexpr dart::compiler::target::word Type_nullability_offset = 33;
1399+
static constexpr dart::compiler::target::word
1400+
TypeParameter_parameterized_class_id_offset = 28;
1401+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 36;
13931402
static constexpr dart::compiler::target::word
13941403
TypeArguments_instantiations_offset = 4;
13951404
static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -1895,6 +1904,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 48;
18951904
static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
18961905
static constexpr dart::compiler::target::word Type_type_state_offset = 60;
18971906
static constexpr dart::compiler::target::word Type_nullability_offset = 61;
1907+
static constexpr dart::compiler::target::word
1908+
TypeParameter_parameterized_class_id_offset = 56;
1909+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 64;
18981910
static constexpr dart::compiler::target::word
18991911
TypeArguments_instantiations_offset = 8;
19001912
static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -2399,6 +2411,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 24;
23992411
static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
24002412
static constexpr dart::compiler::target::word Type_type_state_offset = 32;
24012413
static constexpr dart::compiler::target::word Type_nullability_offset = 33;
2414+
static constexpr dart::compiler::target::word
2415+
TypeParameter_parameterized_class_id_offset = 28;
2416+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 36;
24022417
static constexpr dart::compiler::target::word
24032418
TypeArguments_instantiations_offset = 4;
24042419
static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -2901,6 +2916,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 48;
29012916
static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
29022917
static constexpr dart::compiler::target::word Type_type_state_offset = 60;
29032918
static constexpr dart::compiler::target::word Type_nullability_offset = 61;
2919+
static constexpr dart::compiler::target::word
2920+
TypeParameter_parameterized_class_id_offset = 56;
2921+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 64;
29042922
static constexpr dart::compiler::target::word
29052923
TypeArguments_instantiations_offset = 8;
29062924
static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -3399,6 +3417,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 24;
33993417
static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
34003418
static constexpr dart::compiler::target::word Type_type_state_offset = 32;
34013419
static constexpr dart::compiler::target::word Type_nullability_offset = 33;
3420+
static constexpr dart::compiler::target::word
3421+
TypeParameter_parameterized_class_id_offset = 28;
3422+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 36;
34023423
static constexpr dart::compiler::target::word
34033424
TypeArguments_instantiations_offset = 4;
34043425
static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -3898,6 +3919,9 @@ static constexpr dart::compiler::target::word Type_signature_offset = 48;
38983919
static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
38993920
static constexpr dart::compiler::target::word Type_type_state_offset = 60;
39003921
static constexpr dart::compiler::target::word Type_nullability_offset = 61;
3922+
static constexpr dart::compiler::target::word
3923+
TypeParameter_parameterized_class_id_offset = 56;
3924+
static constexpr dart::compiler::target::word TypeParameter_index_offset = 64;
39013925
static constexpr dart::compiler::target::word
39023926
TypeArguments_instantiations_offset = 8;
39033927
static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -4433,6 +4457,10 @@ static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
44334457
12;
44344458
static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
44354459
static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
4460+
static constexpr dart::compiler::target::word
4461+
AOT_TypeParameter_parameterized_class_id_offset = 28;
4462+
static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
4463+
36;
44364464
static constexpr dart::compiler::target::word
44374465
AOT_TypeArguments_instantiations_offset = 4;
44384466
static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -4991,6 +5019,10 @@ static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
49915019
24;
49925020
static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
49935021
static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
5022+
static constexpr dart::compiler::target::word
5023+
AOT_TypeParameter_parameterized_class_id_offset = 56;
5024+
static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
5025+
64;
49945026
static constexpr dart::compiler::target::word
49955027
AOT_TypeArguments_instantiations_offset = 8;
49965028
static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -5554,6 +5586,10 @@ static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
55545586
24;
55555587
static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
55565588
static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
5589+
static constexpr dart::compiler::target::word
5590+
AOT_TypeParameter_parameterized_class_id_offset = 56;
5591+
static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
5592+
64;
55575593
static constexpr dart::compiler::target::word
55585594
AOT_TypeArguments_instantiations_offset = 8;
55595595
static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -6111,6 +6147,10 @@ static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
61116147
12;
61126148
static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
61136149
static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
6150+
static constexpr dart::compiler::target::word
6151+
AOT_TypeParameter_parameterized_class_id_offset = 28;
6152+
static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
6153+
36;
61146154
static constexpr dart::compiler::target::word
61156155
AOT_TypeArguments_instantiations_offset = 4;
61166156
static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -6662,6 +6702,10 @@ static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
66626702
24;
66636703
static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
66646704
static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
6705+
static constexpr dart::compiler::target::word
6706+
AOT_TypeParameter_parameterized_class_id_offset = 56;
6707+
static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
6708+
64;
66656709
static constexpr dart::compiler::target::word
66666710
AOT_TypeArguments_instantiations_offset = 8;
66676711
static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -7218,6 +7262,10 @@ static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
72187262
24;
72197263
static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
72207264
static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
7265+
static constexpr dart::compiler::target::word
7266+
AOT_TypeParameter_parameterized_class_id_offset = 56;
7267+
static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
7268+
64;
72217269
static constexpr dart::compiler::target::word
72227270
AOT_TypeArguments_instantiations_offset = 8;
72237271
static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =

runtime/vm/compiler/runtime_offsets_list.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@
249249
FIELD(Type, type_class_id_offset) \
250250
FIELD(Type, type_state_offset) \
251251
FIELD(Type, nullability_offset) \
252+
FIELD(TypeParameter, parameterized_class_id_offset) \
253+
FIELD(TypeParameter, index_offset) \
252254
FIELD(TypeArguments, instantiations_offset) \
253255
FIELD(TypeArguments, length_offset) \
254256
FIELD(TypeArguments, nullability_offset) \

runtime/vm/compiler/stub_code_compiler_arm.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,6 +3223,59 @@ void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
32233223
__ Ret();
32243224
}
32253225

3226+
static void BuildTypeParameterTypeTestStub(Assembler* assembler,
3227+
bool allow_null) {
3228+
Label done;
3229+
3230+
if (allow_null) {
3231+
__ CompareObject(TypeTestABI::kInstanceReg, NullObject());
3232+
__ BranchIf(EQUAL, &done);
3233+
}
3234+
3235+
Label function_type_param;
3236+
__ ldrh(TypeTestABI::kScratchReg,
3237+
FieldAddress(TypeTestABI::kDstTypeReg,
3238+
TypeParameter::parameterized_class_id_offset()));
3239+
__ cmp(TypeTestABI::kScratchReg, Operand(kFunctionCid));
3240+
__ BranchIf(EQUAL, &function_type_param);
3241+
3242+
auto handle_case = [&](Register tav) {
3243+
__ CompareObject(tav, NullObject());
3244+
__ BranchIf(EQUAL, &done);
3245+
__ ldrh(
3246+
TypeTestABI::kScratchReg,
3247+
FieldAddress(TypeTestABI::kDstTypeReg, TypeParameter::index_offset()));
3248+
__ add(TypeTestABI::kScratchReg, tav,
3249+
Operand(TypeTestABI::kScratchReg, LSL, 8));
3250+
__ ldr(TypeTestABI::kScratchReg,
3251+
FieldAddress(TypeTestABI::kScratchReg,
3252+
target::TypeArguments::InstanceSize()));
3253+
__ Branch(FieldAddress(TypeTestABI::kScratchReg,
3254+
AbstractType::type_test_stub_entry_point_offset()));
3255+
};
3256+
3257+
// Class type parameter: If dynamic we're done, otherwise dereference type
3258+
// parameter and tail call.
3259+
handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
3260+
3261+
// Function type parameter: If dynamic we're done, otherwise dereference type
3262+
// parameter and tail call.
3263+
__ Bind(&function_type_param);
3264+
handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
3265+
3266+
__ Bind(&done);
3267+
__ Ret();
3268+
}
3269+
3270+
void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
3271+
Assembler* assembler) {
3272+
BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
3273+
}
3274+
3275+
void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
3276+
BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
3277+
}
3278+
32263279
void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
32273280
Label done, call_runtime;
32283281

runtime/vm/compiler/stub_code_compiler_arm64.cc

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3391,6 +3391,63 @@ void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
33913391
__ Ret();
33923392
}
33933393

3394+
static void BuildTypeParameterTypeTestStub(Assembler* assembler,
3395+
bool allow_null) {
3396+
Label done;
3397+
3398+
if (allow_null) {
3399+
__ CompareObject(TypeTestABI::kInstanceReg, NullObject());
3400+
__ BranchIf(EQUAL, &done);
3401+
}
3402+
3403+
Label function_type_param;
3404+
__ ldr(TypeTestABI::kScratchReg,
3405+
FieldAddress(TypeTestABI::kDstTypeReg,
3406+
TypeParameter::parameterized_class_id_offset()),
3407+
kUnsignedHalfword);
3408+
__ cmp(TypeTestABI::kScratchReg, Operand(kFunctionCid));
3409+
__ BranchIf(EQUAL, &function_type_param);
3410+
3411+
auto handle_case = [&](Register tav) {
3412+
__ CompareObject(tav, NullObject());
3413+
__ BranchIf(EQUAL, &done);
3414+
__ ldr(
3415+
TypeTestABI::kScratchReg,
3416+
FieldAddress(TypeTestABI::kDstTypeReg, TypeParameter::index_offset()),
3417+
kUnsignedHalfword);
3418+
__ add(TypeTestABI::kScratchReg, tav,
3419+
Operand(TypeTestABI::kScratchReg, LSL, 8));
3420+
__ ldr(TypeTestABI::kScratchReg,
3421+
FieldAddress(TypeTestABI::kScratchReg,
3422+
target::TypeArguments::InstanceSize()));
3423+
__ ldr(TypeTestABI::kScratchReg,
3424+
FieldAddress(TypeTestABI::kScratchReg,
3425+
AbstractType::type_test_stub_entry_point_offset()));
3426+
__ br(TypeTestABI::kScratchReg);
3427+
};
3428+
3429+
// Class type parameter: If dynamic we're done, otherwise dereference type
3430+
// parameter and tail call.
3431+
handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
3432+
3433+
// Function type parameter: If dynamic we're done, otherwise dereference type
3434+
// parameter and tail call.
3435+
__ Bind(&function_type_param);
3436+
handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
3437+
3438+
__ Bind(&done);
3439+
__ Ret();
3440+
}
3441+
3442+
void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
3443+
Assembler* assembler) {
3444+
BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
3445+
}
3446+
3447+
void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
3448+
BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
3449+
}
3450+
33943451
void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
33953452
Label done, call_runtime;
33963453

runtime/vm/compiler/stub_code_compiler_ia32.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,6 +2630,17 @@ void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
26302630
__ Breakpoint();
26312631
}
26322632

2633+
void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
2634+
Assembler* assembler) {
2635+
// Not implemented on ia32.
2636+
__ Breakpoint();
2637+
}
2638+
2639+
void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
2640+
// Not implemented on ia32.
2641+
__ Breakpoint();
2642+
}
2643+
26332644
void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
26342645
// Not implemented on ia32.
26352646
__ Breakpoint();

runtime/vm/compiler/stub_code_compiler_x64.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,6 +3346,56 @@ void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
33463346
__ Ret();
33473347
}
33483348

3349+
static void BuildTypeParameterTypeTestStub(Assembler* assembler,
3350+
bool allow_null) {
3351+
Label done;
3352+
3353+
if (allow_null) {
3354+
__ CompareObject(TypeTestABI::kInstanceReg, NullObject());
3355+
__ BranchIf(EQUAL, &done);
3356+
}
3357+
3358+
Label function_type_param;
3359+
__ cmpw(FieldAddress(TypeTestABI::kDstTypeReg,
3360+
TypeParameter::parameterized_class_id_offset()),
3361+
Immediate(kFunctionCid));
3362+
__ BranchIf(EQUAL, &function_type_param);
3363+
3364+
auto handle_case = [&](Register tav) {
3365+
__ CompareObject(tav, NullObject());
3366+
__ BranchIf(EQUAL, &done);
3367+
__ movzxw(
3368+
TypeTestABI::kScratchReg,
3369+
FieldAddress(TypeTestABI::kDstTypeReg, TypeParameter::index_offset()));
3370+
__ movq(TypeTestABI::kScratchReg,
3371+
FieldAddress(tav, TypeTestABI::kScratchReg, TIMES_8,
3372+
target::TypeArguments::InstanceSize()));
3373+
__ jmp(FieldAddress(TypeTestABI::kScratchReg,
3374+
AbstractType::type_test_stub_entry_point_offset()));
3375+
};
3376+
3377+
// Class type parameter: If dynamic we're done, otherwise dereference type
3378+
// parameter and tail call.
3379+
handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
3380+
3381+
// Function type parameter: If dynamic we're done, otherwise dereference type
3382+
// parameter and tail call.
3383+
__ Bind(&function_type_param);
3384+
handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
3385+
3386+
__ Bind(&done);
3387+
__ Ret();
3388+
}
3389+
3390+
void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
3391+
Assembler* assembler) {
3392+
BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
3393+
}
3394+
3395+
void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
3396+
BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
3397+
}
3398+
33493399
void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
33503400
Label done, call_runtime;
33513401

runtime/vm/constants_arm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,12 @@ struct TypeTestABI {
326326
static const Register kInstantiatorTypeArgumentsReg = R2;
327327
static const Register kFunctionTypeArgumentsReg = R1;
328328
static const Register kSubtypeTestCacheReg = R3;
329+
static const Register kScratchReg = R4;
329330

330331
static const intptr_t kAbiRegisters =
331332
(1 << kInstanceReg) | (1 << kDstTypeReg) |
332333
(1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
333-
(1 << kSubtypeTestCacheReg);
334+
(1 << kSubtypeTestCacheReg) | (1 << kScratchReg);
334335

335336
// For call to InstanceOfStub.
336337
static const Register kResultReg = R0;

0 commit comments

Comments
 (0)