Skip to content

Commit 6bec28d

Browse files
sstricklCommit Bot
authored and
Commit Bot
committed
[vm] Only check for Smi once when reloading cid for TTS cid checks.
When generating a type testing stub (TTS) for implemented classes, multiple cid range check blocks may be generated, each of which requires reloading the cid. This CL makes it so that only a single Smi check will be generated the first time the cid is loaded, so later checks can just load the cid directly without the Smi case. TEST=vm/cc/TTS Change-Id: I4d76ee34a03cf4a0def268e9f74a096e3c0deb58 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238702 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
1 parent 38a0305 commit 6bec28d

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

runtime/vm/compiler/backend/il.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ struct CidRange : public ZoneAllocated {
201201
CidRange() : cid_start(kIllegalCid), cid_end(kIllegalCid) {}
202202

203203
bool IsSingleCid() const { return cid_start == cid_end; }
204-
bool Contains(intptr_t cid) { return cid_start <= cid && cid <= cid_end; }
204+
bool Contains(intptr_t cid) const {
205+
return cid_start <= cid && cid <= cid_end;
206+
}
205207
int32_t Extent() const { return cid_end - cid_start; }
206208

207209
// The number of class ids this range covers.
@@ -224,7 +226,9 @@ struct CidRangeValue {
224226
: cid_start(other.cid_start), cid_end(other.cid_end) {}
225227

226228
bool IsSingleCid() const { return cid_start == cid_end; }
227-
bool Contains(intptr_t cid) { return cid_start <= cid && cid <= cid_end; }
229+
bool Contains(intptr_t cid) const {
230+
return cid_start <= cid && cid <= cid_end;
231+
}
228232
int32_t Extent() const { return cid_end - cid_start; }
229233

230234
// The number of class ids this range covers.
@@ -244,6 +248,18 @@ struct CidRangeValue {
244248

245249
typedef MallocGrowableArray<CidRangeValue> CidRangeVector;
246250

251+
class CidRangeVectorUtils : public AllStatic {
252+
public:
253+
static bool ContainsCid(const CidRangeVector& ranges, intptr_t cid) {
254+
for (const CidRangeValue& range : ranges) {
255+
if (range.Contains(cid)) {
256+
return true;
257+
}
258+
}
259+
return false;
260+
}
261+
};
262+
247263
class HierarchyInfo : public ThreadStackResource {
248264
public:
249265
explicit HierarchyInfo(Thread* thread)

runtime/vm/type_testing_stubs.cc

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,11 +897,26 @@ bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
897897
CidRangeVector cid_checks_only, type_argument_checks, not_checked;
898898
SplitOnTypeArgumentTests(hi, type, type_class, ranges, &cid_checks_only,
899899
&type_argument_checks, &not_checked);
900+
ASSERT(!CidRangeVectorUtils::ContainsCid(type_argument_checks, kSmiCid));
901+
const bool smi_valid =
902+
CidRangeVectorUtils::ContainsCid(cid_checks_only, kSmiCid);
903+
// If we'll generate any cid checks and Smi isn't a valid subtype, then
904+
// do a single Smi check here, since each generated check requires a fresh
905+
// load of the class id. Otherwise, we'll generate the Smi check as part of
906+
// the cid checks only block.
907+
if (!smi_valid &&
908+
(!cid_checks_only.is_empty() || !type_argument_checks.is_empty())) {
909+
__ BranchIfSmi(TypeTestABI::kInstanceReg, load_failed);
910+
}
900911
if (!cid_checks_only.is_empty()) {
901912
compiler::Label is_subtype, keep_looking;
902913
compiler::Label* check_failed =
903914
type_argument_checks.is_empty() ? load_failed : &keep_looking;
904-
__ LoadClassIdMayBeSmi(class_id_reg, TypeTestABI::kInstanceReg);
915+
if (smi_valid) {
916+
__ LoadClassIdMayBeSmi(class_id_reg, TypeTestABI::kInstanceReg);
917+
} else {
918+
__ LoadClassId(class_id_reg, TypeTestABI::kInstanceReg);
919+
}
905920
BuildOptimizedSubtypeRangeCheck(assembler, cid_checks_only, class_id_reg,
906921
&is_subtype, check_failed);
907922
__ Bind(&is_subtype);
@@ -929,7 +944,7 @@ bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
929944
// and avoid emitting a jump to load_succeeded.
930945
compiler::Label* check_failed =
931946
i < vectors.length() - 1 ? &keep_looking : load_failed;
932-
__ LoadClassIdMayBeSmi(class_id_reg, TypeTestABI::kInstanceReg);
947+
__ LoadClassId(class_id_reg, TypeTestABI::kInstanceReg);
933948
BuildOptimizedSubtypeRangeCheck(assembler, *vector, class_id_reg,
934949
&load_tav, check_failed);
935950
__ Bind(&load_tav);

0 commit comments

Comments
 (0)