[vm] Fix for BuildLoadInstanceTypeArguments in TTS generation.

We must load the class id from the instance prior to _each_
subtype range check, as GenerateCidRangesCheck can clobber that
register during the check.

TEST=Manually tested by @dcharkes using repro from CL 238480.
     Will add regression test on separate CL.

Change-Id: I1de6f4fdd9011f241d785082b4b4866d8b24fcfb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238582
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
Tess Strickland
2022-03-25 10:23:50 +00:00
committed by Commit Bot
parent 61954676ea
commit e2fa5d8d09
+8 -7
View File
@@ -570,9 +570,10 @@ static void CommentSkippedClasses(compiler::Assembler* assembler,
}
// Builds a cid range check for the concrete subclasses and implementors of
// type. Assumes cid to check is already in TTSInternalRegs::kScratchReg. Falls
// through or jumps to check_succeeded if the range contains the cid, else
// jumps to check_failed.
// type. Falls through or jumps to check_succeeded if the range contains the
// cid, else jumps to check_failed.
//
// Clobbers class_id_reg.
void TypeTestingStubGenerator::BuildOptimizedSubtypeRangeCheck(
compiler::Assembler* assembler,
const CidRangeVector& ranges,
@@ -591,12 +592,9 @@ void TypeTestingStubGenerator::
const Type& type,
const Class& type_class) {
ASSERT(hi->CanUseGenericSubtypeRangeCheckFor(type));
compiler::Label check_failed;
compiler::Label check_failed, load_succeeded;
// a) First we perform subtype cid-range checks and load the instance type
// arguments based on which check succeeded.
__ LoadClassIdMayBeSmi(TTSInternalRegs::kScratchReg,
TypeTestABI::kInstanceReg);
compiler::Label load_succeeded;
if (BuildLoadInstanceTypeArguments(assembler, hi, type, type_class,
TTSInternalRegs::kScratchReg,
TTSInternalRegs::kInstanceTypeArgumentsReg,
@@ -879,6 +877,7 @@ bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
const intptr_t tav_offset =
compiler::target::Class::TypeArgumentsFieldOffset(type_class);
compiler::Label is_subtype;
__ LoadClassIdMayBeSmi(class_id_reg, TypeTestABI::kInstanceReg);
BuildOptimizedSubtypeRangeCheck(assembler, ranges, class_id_reg,
&is_subtype, load_failed);
__ Bind(&is_subtype);
@@ -902,6 +901,7 @@ bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
compiler::Label is_subtype, keep_looking;
compiler::Label* check_failed =
type_argument_checks.is_empty() ? load_failed : &keep_looking;
__ LoadClassIdMayBeSmi(class_id_reg, TypeTestABI::kInstanceReg);
BuildOptimizedSubtypeRangeCheck(assembler, cid_checks_only, class_id_reg,
&is_subtype, check_failed);
__ Bind(&is_subtype);
@@ -929,6 +929,7 @@ bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
// and avoid emitting a jump to load_succeeded.
compiler::Label* check_failed =
i < vectors.length() - 1 ? &keep_looking : load_failed;
__ LoadClassIdMayBeSmi(class_id_reg, TypeTestABI::kInstanceReg);
BuildOptimizedSubtypeRangeCheck(assembler, *vector, class_id_reg,
&load_tav, check_failed);
__ Bind(&load_tav);