[modular_aot] Fixes for code generation of TypeCast
* Use exact code pattern for calling TTS which is expected by the VM at runtime. * Always set instantiator/function type arguments registers for TTS. * List all registers potentially clobbered by TTS. Issue: https://github.com/dart-lang/sdk/issues/61635 Change-Id: I011bcfc8b755864271877cc36d365ba2b5f10648 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/509480 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
19db32f041
commit
ea1360fbaf
@@ -19,6 +19,7 @@ import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/code_generator.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
import 'package:native_compiler/runtime/names.dart';
|
||||
import 'package:native_compiler/runtime/type_utils.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
|
||||
@@ -1042,7 +1043,7 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
_asm.loadFromPool(TypeTestingStub.dstTypeReg, dartType);
|
||||
}
|
||||
_asm.ldr(
|
||||
tempReg,
|
||||
TypeTestingStub.entryPointReg,
|
||||
_asm.fieldAddress(
|
||||
TypeTestingStub.dstTypeReg,
|
||||
vmOffsets.AbstractType_type_test_stub_entry_point_offset,
|
||||
@@ -1061,8 +1062,16 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
hasFunctionTypeArgs: hasFunctionTypeArgs,
|
||||
),
|
||||
);
|
||||
_asm.loadFromPool(TypeTestingStub.subtypeTestCacheReg, stc);
|
||||
_asm.blr(tempReg);
|
||||
if (instr.inputCount == 1) {
|
||||
_asm.mov(TypeTestingStub.instantiatorTypeArgumentsReg, nullReg);
|
||||
_asm.mov(TypeTestingStub.functionTypeArgumentsReg, nullReg);
|
||||
}
|
||||
// VM expects exact code pattern for type testing stub calling sequence.
|
||||
_asm.loadFromPool(
|
||||
TypeTestingStub.subtypeTestCacheReg,
|
||||
SubtypeTestCacheWithName(stc, Name('', null)),
|
||||
);
|
||||
_asm.blr(TypeTestingStub.entryPointReg);
|
||||
}
|
||||
|
||||
_asm.bind(done);
|
||||
|
||||
@@ -241,10 +241,15 @@ final class Arm64Constraints extends Constraints {
|
||||
TypeTestingStub.functionTypeArgumentsReg,
|
||||
],
|
||||
],
|
||||
const [
|
||||
TypeTestingStub.dstTypeReg,
|
||||
TypeTestingStub.subtypeTestCacheReg,
|
||||
TypeTestingStub.scratchReg,
|
||||
// Type testing stub can call runtime without preserving registers.
|
||||
[
|
||||
for (final r in allocatableRegisters)
|
||||
if (r != TypeTestingStub.instanceReg &&
|
||||
((instr.inputCount == 1) ||
|
||||
(r != TypeTestingStub.instantiatorTypeArgumentsReg &&
|
||||
r != TypeTestingStub.functionTypeArgumentsReg)))
|
||||
r,
|
||||
...allocatableFPRegisters,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ final class TypeTestingStub {
|
||||
static const Register subtypeTestCacheReg = R3;
|
||||
static const Register scratchReg = R4;
|
||||
static const Register subtypeTestCacheResultReg = R7;
|
||||
static const Register entryPointReg = R9;
|
||||
}
|
||||
|
||||
final class InstantiateTypeArgumentsStub {
|
||||
|
||||
@@ -132,3 +132,22 @@ final class SubtypeTestCache {
|
||||
// Use identity hashCode and == as separate subtype test caches are
|
||||
// used for each type check.
|
||||
}
|
||||
|
||||
/// A pair (subtype test cache, name). VM decodes type testing stub
|
||||
/// calling sequence and reads name from object pool immediately
|
||||
/// after subtype test cache when throwing type errors.
|
||||
final class SubtypeTestCacheWithName extends PairSpecializedEntry {
|
||||
final SubtypeTestCache stc;
|
||||
final Name name;
|
||||
|
||||
SubtypeTestCacheWithName(this.stc, this.name);
|
||||
|
||||
@override
|
||||
int get hashCode => finalizeHash(combineHash(stc.hashCode, name.hashCode));
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is SubtypeTestCacheWithName &&
|
||||
this.stc == other.stc &&
|
||||
this.name == other.name;
|
||||
}
|
||||
|
||||
@@ -1631,6 +1631,9 @@ final class ObjectPoolSerializationCluster extends SerializationCluster {
|
||||
entry.selector,
|
||||
);
|
||||
serializer.push(icData);
|
||||
case SubtypeTestCacheWithName():
|
||||
serializer.push(entry.stc);
|
||||
serializer.push(entry.name);
|
||||
case ReservedEntry():
|
||||
break;
|
||||
}
|
||||
@@ -1673,6 +1676,11 @@ final class ObjectPoolSerializationCluster extends SerializationCluster {
|
||||
case DynamicCallEntry():
|
||||
serializer.writeUint(ObjectPoolEntryKind.dynamicCall.index);
|
||||
serializer.writeRefId(icDatas[entry]);
|
||||
case SubtypeTestCacheWithName():
|
||||
serializer.writeUint(ObjectPoolEntryKind.objectRef.index);
|
||||
serializer.writeRefId(entry.stc);
|
||||
serializer.writeUint(ObjectPoolEntryKind.objectRef.index);
|
||||
serializer.writeRefId(entry.name);
|
||||
case ReservedEntry():
|
||||
}
|
||||
} else if (entry is UnboxedIntConstant) {
|
||||
|
||||
@@ -30,9 +30,9 @@ B0 = EntryBlock()
|
||||
v16 = TypeTest(v3, v12, v1, List<C.typeParameters.U%>) # RA: R7 <- (R0, R2, R1) temps: [R8, R3, R4]
|
||||
ParallelMove output(R7 -> vloc:R7)
|
||||
DirectCall print(v16) # RA: R0 <- (R7) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(param[0] -> R5, param[2] -> R1, stack[0] -> R2)
|
||||
ParallelMove input(vloc:R1 -> R0, vloc:R2 -> R2, vloc:R5 -> R1)
|
||||
v19 = TypeCast(v3, v37, v1, Map<C.T%, C.typeParameters.U%>) # RA: R0 <- (R0, R2, R1) temps: [R8, R3, R4]
|
||||
ParallelMove output(param[0] -> R0, param[2] -> R1, stack[0] -> R2)
|
||||
ParallelMove input(vloc:R1 -> R0, vloc:R2 -> R2, vloc:R0 -> R1)
|
||||
v19 = TypeCast(v3, v37, v1, Map<C.T%, C.typeParameters.U%>) # RA: R0 <- (R0, R2, R1) temps: [R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
DirectCall print(v19) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
v21 = AllocateClosure() # RA: R0 <- () temps: [R2, R3, R4]
|
||||
|
||||
@@ -401,15 +401,15 @@ B6 = TargetBlock() idom:B0
|
||||
ParallelMove output(param[0] -> R0)
|
||||
v17 = InterfaceCall getter StreamController._varData(v1) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0, param[0] -> R1)
|
||||
v25 = LoadInstanceField(StreamController.#typeArguments, v1) # RA: R5 <- (R1)
|
||||
ParallelMove output(R5 -> stack[0])
|
||||
ParallelMove input(vloc:R0 -> R0, vloc:R5 -> R2, NullConstant(null) -> R1)
|
||||
v18 = TypeCast(v17, v25, v13, _StreamControllerAddStreamState<StreamController.T%>) # RA: R0 <- (R0, R2, R1) temps: [R8, R3, R4]
|
||||
v25 = LoadInstanceField(StreamController.#typeArguments, v1) # RA: R1 <- (R1)
|
||||
ParallelMove output(R1 -> stack[0])
|
||||
ParallelMove input(vloc:R0 -> R0, vloc:R1 -> R2, NullConstant(null) -> R1)
|
||||
v18 = TypeCast(v17, v25, v13, _StreamControllerAddStreamState<StreamController.T%>) # RA: R0 <- (R0, R2, R1) temps: [R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
v21 = InterfaceCall getter _StreamControllerAddStreamState._varData(v18) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0, stack[0] -> R2)
|
||||
ParallelMove input(vloc:R0 -> R0, vloc:R2 -> R2, NullConstant(null) -> R1)
|
||||
v22 = TypeCast(v21, v25, v13, _PendingEvents<StreamController.T%>?) # RA: R0 <- (R0, R2, R1) temps: [R8, R3, R4]
|
||||
v22 = TypeCast(v21, v25, v13, _PendingEvents<StreamController.T%>?) # RA: R0 <- (R0, R2, R1) temps: [R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
ParallelMove input(vloc:R0 -> R0)
|
||||
Return(v22) # RA: (R0)
|
||||
@@ -420,7 +420,7 @@ B7 = TargetBlock() idom:B0
|
||||
ParallelMove output(R0 -> vloc:R0, param[0] -> R1)
|
||||
v26 = LoadInstanceField(StreamController.#typeArguments, v1) # RA: R2 <- (R1)
|
||||
ParallelMove input(vloc:R0 -> R0, vloc:R2 -> R2, NullConstant(null) -> R1)
|
||||
v14 = TypeCast(v12, v26, v13, _PendingEvents<StreamController.T%>?) # RA: R0 <- (R0, R2, R1) temps: [R8, R3, R4]
|
||||
v14 = TypeCast(v12, v26, v13, _PendingEvents<StreamController.T%>?) # RA: R0 <- (R0, R2, R1) temps: [R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
ParallelMove input(vloc:R0 -> R0)
|
||||
Return(v14) # RA: (R0)
|
||||
@@ -1198,7 +1198,7 @@ B577 = TargetBlock() idom:B570
|
||||
v588 = InterfaceCall List.[](v585, v788) # RA: R0 <- (-, R1) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
ParallelMove input(vloc:R0 -> R0)
|
||||
v589 = TypeCast(v588, num) # RA: R0 <- (R0) temps: [R8, R3, R4]
|
||||
v589 = TypeCast(v588, num) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R1, stack[20] -> V0)
|
||||
v789 = BoxDouble(v564) # RA: R4 <- (V0) temps: [R0, R3, R2]
|
||||
v590 = InterfaceCall double./(v789, v589) # RA: R0 <- (R4, R1) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -1230,7 +1230,7 @@ B609 = TargetBlock() idom:B597
|
||||
v618 = InterfaceCall List.[](v585, v794) # RA: R0 <- (-, R4) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
ParallelMove input(vloc:R0 -> R0)
|
||||
v619 = TypeCast(v618, num) # RA: R0 <- (R0) temps: [R8, R3, R4]
|
||||
v619 = TypeCast(v618, num) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R2, stack[20] -> V0)
|
||||
v795 = BoxDouble(v564) # RA: R4 <- (V0) temps: [R1, R3, R0]
|
||||
v620 = InterfaceCall double.*(v795, v619) # RA: R0 <- (R4, R2) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -1675,12 +1675,13 @@ B0 = EntryBlock()
|
||||
v2 = Parameter(b) # RA: param[1] <- ()
|
||||
ParallelMove output(param[1] -> vloc:R1, param[0] -> vloc:R0)
|
||||
ParallelMove input(vloc:R0 -> R0)
|
||||
v4 = TypeCast(v1, Comparable<dynamic>) # RA: R0 <- (R0) temps: [R8, R3, R4]
|
||||
ParallelMove output(R0 -> vloc:R2)
|
||||
v4 = TypeCast(v1, Comparable<dynamic>) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0, param[1] -> R1)
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
ParallelMove input(vloc:R1 -> R0)
|
||||
v6 = TypeCast(v2, Comparable<dynamic>) # RA: R0 <- (R0) temps: [R8, R3, R4]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
v7 = DirectCall Comparable.compare(v4, v6) # RA: R0 <- (R2, R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
v6 = TypeCast(v2, Comparable<dynamic>) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0, stack[0] -> R1)
|
||||
v7 = DirectCall Comparable.compare(v4, v6) # RA: R0 <- (R1, R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
ParallelMove input(vloc:R0 -> R0)
|
||||
Return(v7) # RA: (R0)
|
||||
|
||||
Reference in New Issue
Block a user