Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b48c8b1

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm] Re-order ICData entries to allow CID and count to be accessed with a load-pair.
Bug: dart-lang/sdk#36731 Change-Id: Ia91ddb7e8991a5ab227ab8758173a99141c259be Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103004 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent 959e7df commit b48c8b1

File tree

7 files changed

+48
-57
lines changed

7 files changed

+48
-57
lines changed

runtime/vm/compiler/runtime_api.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ word ICData::TargetIndexFor(word num_args) {
368368
return dart::ICData::TargetIndexFor(num_args);
369369
}
370370

371-
word ICData::ExactnessOffsetFor(word num_args) {
372-
return dart::ICData::ExactnessOffsetFor(num_args);
371+
word ICData::ExactnessIndexFor(word num_args) {
372+
return dart::ICData::ExactnessIndexFor(num_args);
373373
}
374374

375375
word ICData::TestEntryLengthFor(word num_args, bool exactness_check) {

runtime/vm/compiler/runtime_api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ class ICData : public AllStatic {
419419
static word CodeIndexFor(word num_args);
420420
static word CountIndexFor(word num_args);
421421
static word TargetIndexFor(word num_args);
422-
static word ExactnessOffsetFor(word num_args);
422+
static word ExactnessIndexFor(word num_args);
423423
static word TestEntryLengthFor(word num_args, bool exactness_check);
424424
static word EntryPointIndexFor(word num_args);
425425
static word NumArgsTestedShift();

runtime/vm/compiler/stub_code_compiler_x64.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
20362036
const intptr_t count_offset =
20372037
target::ICData::CountIndexFor(num_args) * target::kWordSize;
20382038
const intptr_t exactness_offset =
2039-
target::ICData::ExactnessOffsetFor(num_args) * target::kWordSize;
2039+
target::ICData::ExactnessIndexFor(num_args) * target::kWordSize;
20402040

20412041
__ Bind(&loop);
20422042
for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {

runtime/vm/interpreter.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ DART_FORCE_INLINE bool Interpreter::InstanceCall1(Thread* thread,
793793
intptr_t i;
794794
for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
795795
if (cache->data()[i + 0] == receiver_cid) {
796-
top[0] = cache->data()[i + kCheckedArgs];
796+
top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
797797
found = true;
798798
break;
799799
}
@@ -841,7 +841,7 @@ DART_FORCE_INLINE bool Interpreter::InstanceCall2(Thread* thread,
841841
for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
842842
if ((cache->data()[i + 0] == receiver_cid) &&
843843
(cache->data()[i + 1] == arg0_cid)) {
844-
top[0] = cache->data()[i + kCheckedArgs];
844+
top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
845845
found = true;
846846
break;
847847
}

runtime/vm/object.cc

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13474,7 +13474,8 @@ void ICData::ClearAndSetStaticTarget(const Function& func) const {
1347413474
}
1347513475
// The final entry is always the sentinel.
1347613476
ASSERT(IsSentinelAt(len - 1));
13477-
if (NumArgsTested() == 0) {
13477+
const intptr_t num_args_tested = NumArgsTested();
13478+
if (num_args_tested == 0) {
1347813479
// No type feedback is being collected.
1347913480
const Array& data = Array::Handle(entries());
1348013481
// Static calls with no argument checks hold only one target and the
@@ -13483,11 +13484,11 @@ void ICData::ClearAndSetStaticTarget(const Function& func) const {
1348313484
// Static calls with no argument checks only need two words.
1348413485
ASSERT(TestEntryLength() == 2);
1348513486
// Set the target.
13486-
data.SetAt(0, func);
13487+
data.SetAt(TargetIndexFor(num_args_tested), func);
1348713488
// Set count to 0 as this is called during compilation, before the
1348813489
// call has been executed.
1348913490
const Smi& value = Smi::Handle(Smi::New(0));
13490-
data.SetAt(1, value);
13491+
data.SetAt(CountIndexFor(num_args_tested), value);
1349113492
} else {
1349213493
// Type feedback on arguments is being collected.
1349313494
const Array& data = Array::Handle(entries());
@@ -13501,9 +13502,9 @@ void ICData::ClearAndSetStaticTarget(const Function& func) const {
1350113502
for (intptr_t i = 0; i < NumArgsTested(); i++) {
1350213503
data.SetAt(i, object_cid);
1350313504
}
13504-
data.SetAt(NumArgsTested(), func);
13505+
data.SetAt(TargetIndexFor(num_args_tested), func);
1350513506
const Smi& value = Smi::Handle(Smi::New(0));
13506-
data.SetAt(NumArgsTested() + 1, value);
13507+
data.SetAt(CountIndexFor(num_args_tested), value);
1350713508
}
1350813509
}
1350913510

@@ -13573,11 +13574,11 @@ void ICData::AddTarget(const Function& target) const {
1357313574
WriteSentinel(data, TestEntryLength());
1357413575
intptr_t data_pos = old_num * TestEntryLength();
1357513576
ASSERT(!target.IsNull());
13576-
data.SetAt(data_pos++, target);
13577+
data.SetAt(data_pos + TargetIndexFor(NumArgsTested()), target);
1357713578
// Set count to 0 as this is called during compilation, before the
1357813579
// call has been executed.
1357913580
const Smi& value = Smi::Handle(Smi::New(0));
13580-
data.SetAt(data_pos, value);
13581+
data.SetAt(data_pos + CountIndexFor(NumArgsTested()), value);
1358113582
// Multithreaded access to ICData requires setting of array to be the last
1358213583
// operation.
1358313584
set_entries(data);
@@ -13608,22 +13609,23 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
1360813609
ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
1360913610
DEBUG_ASSERT(!HasCheck(class_ids));
1361013611
ASSERT(NumArgsTested() > 1); // Otherwise use 'AddReceiverCheck'.
13611-
ASSERT(class_ids.length() == NumArgsTested());
13612+
const intptr_t num_args_tested = NumArgsTested();
13613+
ASSERT(class_ids.length() == num_args_tested);
1361213614
const intptr_t old_num = NumberOfChecks();
1361313615
Array& data = Array::Handle(entries());
1361413616
// ICData of static calls with NumArgsTested() > 0 have initially a
1361513617
// dummy set of cids entered (see ICData::AddTarget). That entry is
1361613618
// overwritten by first real type feedback data.
1361713619
if (old_num == 1) {
1361813620
bool has_dummy_entry = true;
13619-
for (intptr_t i = 0; i < NumArgsTested(); i++) {
13621+
for (intptr_t i = 0; i < num_args_tested; i++) {
1362013622
if (Smi::Value(Smi::RawCast(data.At(i))) != kObjectCid) {
1362113623
has_dummy_entry = false;
1362213624
break;
1362313625
}
1362413626
}
1362513627
if (has_dummy_entry) {
13626-
ASSERT(target.raw() == data.At(NumArgsTested()));
13628+
ASSERT(target.raw() == data.At(TargetIndexFor(num_args_tested)));
1362713629
// Replace dummy entry.
1362813630
Smi& value = Smi::Handle();
1362913631
for (intptr_t i = 0; i < NumArgsTested(); i++) {
@@ -13643,12 +13645,12 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
1364313645
// kIllegalCid is used as terminating value, do not add it.
1364413646
ASSERT(class_ids[i] != kIllegalCid);
1364513647
value = Smi::New(class_ids[i]);
13646-
data.SetAt(data_pos++, value);
13648+
data.SetAt(data_pos + i, value);
1364713649
}
1364813650
ASSERT(!target.IsNull());
13649-
data.SetAt(data_pos++, target);
13651+
data.SetAt(data_pos + TargetIndexFor(num_args_tested), target);
1365013652
value = Smi::New(count);
13651-
data.SetAt(data_pos++, value);
13653+
data.SetAt(data_pos + CountIndexFor(num_args_tested), value);
1365213654
// Multithreaded access to ICData requires setting of array to be the last
1365313655
// operation.
1365413656
set_entries(data);
@@ -13697,7 +13699,8 @@ void ICData::AddReceiverCheck(intptr_t receiver_class_id,
1369713699
ASSERT(!HasCheck(class_ids));
1369813700
#endif // DEBUG
1369913701
ASSERT(!target.IsNull());
13700-
ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'.
13702+
const intptr_t kNumArgsTested = 1;
13703+
ASSERT(NumArgsTested() == kNumArgsTested); // Otherwise use 'AddCheck'.
1370113704
ASSERT(receiver_class_id != kIllegalCid);
1370213705

1370313706
intptr_t index = -1;
@@ -13714,19 +13717,21 @@ void ICData::AddReceiverCheck(intptr_t receiver_class_id,
1371413717
}
1371513718
data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
1371613719
if (Isolate::Current()->compilation_allowed()) {
13717-
data.SetAt(data_pos + 1, target);
13718-
data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count)));
13720+
data.SetAt(data_pos + TargetIndexFor(kNumArgsTested), target);
13721+
data.SetAt(data_pos + CountIndexFor(kNumArgsTested),
13722+
Smi::Handle(Smi::New(count)));
1371913723
if (is_tracking_exactness()) {
13720-
data.SetAt(data_pos + 3, Smi::Handle(Smi::New(exactness.Encode())));
13724+
data.SetAt(data_pos + ExactnessIndexFor(kNumArgsTested),
13725+
Smi::Handle(Smi::New(exactness.Encode())));
1372113726
}
1372213727
} else {
1372313728
// Precompilation only, after all functions have been compiled.
1372413729
ASSERT(target.HasCode());
1372513730
const Code& code = Code::Handle(target.CurrentCode());
1372613731
const Smi& entry_point =
1372713732
Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
13728-
data.SetAt(data_pos + 1, code);
13729-
data.SetAt(data_pos + 2, entry_point);
13733+
data.SetAt(data_pos + CodeIndexFor(kNumArgsTested), code);
13734+
data.SetAt(data_pos + EntryPointIndexFor(kNumArgsTested), entry_point);
1373013735
}
1373113736
// Multithreaded access to ICData requires setting of array to be the last
1373213737
// operation.
@@ -13738,9 +13743,10 @@ StaticTypeExactnessState ICData::GetExactnessAt(intptr_t index) const {
1373813743
return StaticTypeExactnessState::NotTracking();
1373913744
}
1374013745
const Array& data = Array::Handle(entries());
13741-
intptr_t data_pos = index * TestEntryLength();
13746+
intptr_t data_pos =
13747+
index * TestEntryLength() + ExactnessIndexFor(NumArgsTested());
1374213748
return StaticTypeExactnessState::Decode(
13743-
Smi::Value(Smi::RawCast(data.At(data_pos + NumArgsTested() + 2))));
13749+
Smi::Value(Smi::RawCast(data.At(data_pos))));
1374413750
}
1374513751

1374613752
void ICData::GetCheckAt(intptr_t index,
@@ -13753,9 +13759,9 @@ void ICData::GetCheckAt(intptr_t index,
1375313759
const Array& data = Array::Handle(entries());
1375413760
intptr_t data_pos = index * TestEntryLength();
1375513761
for (intptr_t i = 0; i < NumArgsTested(); i++) {
13756-
class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
13762+
class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos + i))));
1375713763
}
13758-
(*target) ^= data.At(data_pos++);
13764+
(*target) ^= data.At(data_pos + TargetIndexFor(NumArgsTested()));
1375913765
}
1376013766

1376113767
bool ICData::IsSentinelAt(intptr_t index) const {
@@ -13794,7 +13800,7 @@ void ICData::GetOneClassCheckAt(intptr_t index,
1379413800
const Array& data = Array::Handle(entries());
1379513801
const intptr_t data_pos = index * TestEntryLength();
1379613802
*class_id = Smi::Value(Smi::RawCast(data.At(data_pos)));
13797-
*target ^= data.At(data_pos + 1);
13803+
*target ^= data.At(data_pos + TargetIndexFor(NumArgsTested()));
1379813804
}
1379913805

1380013806
intptr_t ICData::GetCidAt(intptr_t index) const {
@@ -13821,7 +13827,8 @@ intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const {
1382113827

1382213828
RawFunction* ICData::GetTargetAt(intptr_t index) const {
1382313829
ASSERT(Isolate::Current()->compilation_allowed());
13824-
const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
13830+
const intptr_t data_pos =
13831+
index * TestEntryLength() + TargetIndexFor(NumArgsTested());
1382513832
ASSERT(Object::Handle(Array::Handle(entries()).At(data_pos)).IsFunction());
1382613833

1382713834
NoSafepointScope no_safepoint;
@@ -13830,7 +13837,8 @@ RawFunction* ICData::GetTargetAt(intptr_t index) const {
1383013837
}
1383113838

1383213839
RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const {
13833-
const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
13840+
const intptr_t data_pos =
13841+
index * TestEntryLength() + TargetIndexFor(NumArgsTested());
1383413842

1383513843
NoSafepointScope no_safepoint;
1383613844
RawArray* raw_data = entries();
@@ -13894,18 +13902,6 @@ void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const {
1389413902
}
1389513903

1389613904
#if !defined(DART_PRECOMPILED_RUNTIME)
13897-
RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id,
13898-
intptr_t* count_return) const {
13899-
const intptr_t len = NumberOfChecks();
13900-
for (intptr_t i = 0; i < len; i++) {
13901-
if (GetReceiverClassIdAt(i) == class_id) {
13902-
*count_return = GetCountAt(i);
13903-
return GetTargetAt(i);
13904-
}
13905-
}
13906-
return Function::null();
13907-
}
13908-
1390913905
RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid,
1391013906
const Function& target) const {
1391113907
ASSERT(!IsNull());

runtime/vm/object.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,8 +1775,6 @@ class ICData : public Object {
17751775
intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
17761776

17771777
RawFunction* GetTargetAt(intptr_t index) const;
1778-
RawFunction* GetTargetForReceiverClassId(intptr_t class_id,
1779-
intptr_t* count_return) const;
17801778

17811779
RawObject* GetTargetOrCodeAt(intptr_t index) const;
17821780
void SetCodeAt(intptr_t index, const Code& value) const;
@@ -1829,16 +1827,13 @@ class ICData : public Object {
18291827
static intptr_t TestEntryLengthFor(intptr_t num_args,
18301828
bool tracking_exactness);
18311829

1832-
static intptr_t TargetIndexFor(intptr_t num_args) { return num_args; }
1833-
static intptr_t CodeIndexFor(intptr_t num_args) { return num_args; }
1830+
static intptr_t CountIndexFor(intptr_t num_args) { return num_args; }
1831+
static intptr_t EntryPointIndexFor(intptr_t num_args) { return num_args; }
18341832

1835-
static intptr_t CountIndexFor(intptr_t num_args) { return (num_args + 1); }
1836-
static intptr_t EntryPointIndexFor(intptr_t num_args) {
1837-
return (num_args + 1);
1838-
}
1839-
static intptr_t ExactnessOffsetFor(intptr_t num_args) {
1840-
return (num_args + 2);
1841-
}
1833+
static intptr_t TargetIndexFor(intptr_t num_args) { return num_args + 1; }
1834+
static intptr_t CodeIndexFor(intptr_t num_args) { return num_args + 1; }
1835+
1836+
static intptr_t ExactnessIndexFor(intptr_t num_args) { return num_args + 2; }
18421837

18431838
bool IsUsedAt(intptr_t i) const;
18441839

runtime/vm/simulator_dbc.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread,
874874
intptr_t i;
875875
for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
876876
if (cache->data()[i + 0] == receiver_cid) {
877-
top[0] = cache->data()[i + kCheckedArgs];
877+
top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
878878
found = true;
879879
break;
880880
}
@@ -920,7 +920,7 @@ DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread,
920920
for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
921921
if ((cache->data()[i + 0] == receiver_cid) &&
922922
(cache->data()[i + 1] == arg0_cid)) {
923-
top[0] = cache->data()[i + kCheckedArgs];
923+
top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
924924
found = true;
925925
break;
926926
}

0 commit comments

Comments
 (0)