[vm/concurrency] Use ICData::NewWithCheck() when creating new ICData with initial checks
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Refactoring, covered by existing test suite.
Change-Id: Idb1a3e8024dc257bac31267d7f9657c6faa3cbcb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174464
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 1844961..160aa54 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -14879,6 +14879,24 @@
}
#endif
+void ICData::SetTargetAtPos(const Array& data,
+ intptr_t data_pos,
+ intptr_t num_args_tested,
+ const Function& target) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // JIT
+ data.SetAt(data_pos + TargetIndexFor(num_args_tested), target);
+#else
+ // AOT
+ ASSERT(target.HasCode());
+ const Code& code = Code::Handle(target.CurrentCode());
+ const Smi& entry_point =
+ Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
+ data.SetAt(data_pos + CodeIndexFor(num_args_tested), code);
+ data.SetAt(data_pos + EntryPointIndexFor(num_args_tested), entry_point);
+#endif
+}
+
const char* ICData::ToCString() const {
Zone* zone = Thread::Current()->zone();
const String& name = String::Handle(zone, target_name());
@@ -15330,24 +15348,15 @@
data_pos = 0;
}
data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
+ SetTargetAtPos(data, data_pos, kNumArgsTested, target);
#if !defined(DART_PRECOMPILED_RUNTIME)
- // JIT
- data.SetAt(data_pos + TargetIndexFor(kNumArgsTested), target);
data.SetAt(data_pos + CountIndexFor(kNumArgsTested),
Smi::Handle(Smi::New(count)));
if (is_tracking_exactness()) {
data.SetAt(data_pos + ExactnessIndexFor(kNumArgsTested),
Smi::Handle(Smi::New(exactness.Encode())));
}
-#else
- // AOT
- ASSERT(target.HasCode());
- const Code& code = Code::Handle(target.CurrentCode());
- const Smi& entry_point =
- Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
- data.SetAt(data_pos + CodeIndexFor(kNumArgsTested), code);
- data.SetAt(data_pos + EntryPointIndexFor(kNumArgsTested), entry_point);
#endif
// Multithreaded access to ICData requires setting of array to be the last
@@ -15822,9 +15831,13 @@
cid = Smi::New((*cids)[i]);
array.SetAt(i, cid);
}
+
+ SetTargetAtPos(array, 0, num_args_tested, target);
+#if !defined(DART_PRECOMPILED_RUNTIME)
array.SetAt(CountIndexFor(num_args_tested), Object::smi_zero());
- array.SetAt(TargetIndexFor(num_args_tested), target);
+#endif
WriteSentinel(array, entry_len);
+
result.set_entries(array);
return result.raw();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index b5d8548..3c70ead 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2258,6 +2258,11 @@
void SetNumArgsTested(intptr_t value) const;
void SetReceiversStaticType(const AbstractType& type) const;
+ static void SetTargetAtPos(const Array& data,
+ intptr_t data_pos,
+ intptr_t num_args_tested,
+ const Function& target);
+
// This bit is set when a call site becomes megamorphic and starts using a
// MegamorphicCache instead of ICData. It means that the entries in the
// ICData are incomplete and the MegamorphicCache needs to also be consulted
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index f241c0c..8ef9463 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1596,6 +1596,9 @@
void DoMegamorphicMiss(const MegamorphicCache& data,
const Function& target_function);
+ ICDataPtr NewICData();
+ ICDataPtr NewICDataWithTarget(intptr_t cid, const Function& target);
+
Isolate* isolate_;
Thread* thread_;
Zone* zone_;
@@ -1613,16 +1616,11 @@
void SwitchableCallHandler::DoUnlinkedCall(const UnlinkedCall& unlinked,
const Function& target_function) {
- const String& name = String::Handle(zone_, unlinked.target_name());
- const Array& descriptor =
- Array::Handle(zone_, unlinked.arguments_descriptor());
- const ICData& ic_data =
- ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
- DeoptId::kNone, 1, /* args_tested */
- ICData::kInstance));
- if (!target_function.IsNull()) {
- ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
- }
+ const auto& ic_data = ICData::Handle(
+ zone_,
+ target_function.IsNull()
+ ? NewICData()
+ : NewICDataWithTarget(receiver_.GetClassId(), target_function));
Object& object = Object::Handle(zone_, ic_data.raw());
Code& code = Code::Handle(zone_, StubCode::ICCallThroughCode().raw());
@@ -1746,14 +1744,10 @@
zone_,
Resolve(thread_, zone_, old_receiver_class, name_, args_descriptor_));
- const ICData& ic_data = ICData::Handle(
- zone_, ICData::New(caller_function_, name_, args_descriptor_,
- DeoptId::kNone, 1, /* args_tested */
- ICData::kInstance));
- // Add the first target.
- if (!old_target.IsNull()) {
- ic_data.AddReceiverCheck(old_expected_cid, old_target);
- }
+ const auto& ic_data = ICData::Handle(
+ zone_, old_target.IsNull()
+ ? NewICData()
+ : NewICDataWithTarget(old_expected_cid, old_target));
if (is_monomorphic_hit) {
// The site just have been updated to monomorphic state with same
@@ -1794,6 +1788,7 @@
arguments_.SetArgAt(0, stub);
arguments_.SetReturn(ic_data);
#else // JIT
+
const ICData& ic_data = ICData::Handle(
zone_,
FindICDataForInstanceCall(zone_, caller_code_, caller_frame_->pc()));
@@ -1836,13 +1831,11 @@
Function::Handle(zone_, Function::RawCast(old_target_code.owner()));
// We lost the original ICData when we patched to the monomorphic case.
- const ICData& ic_data = ICData::Handle(
- zone_, ICData::New(caller_function_, name_, args_descriptor_,
- DeoptId::kNone, 1, /* args_tested */
- ICData::kInstance));
- if (!target_function.IsNull()) {
- ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
- }
+ const auto& ic_data = ICData::Handle(
+ zone_,
+ target_function.IsNull()
+ ? NewICData()
+ : NewICDataWithTarget(receiver_.GetClassId(), target_function));
intptr_t lower = data.lower_limit();
intptr_t upper = data.upper_limit();
@@ -1957,6 +1950,20 @@
arguments_.SetReturn(data);
}
+ICDataPtr SwitchableCallHandler::NewICData() {
+ return ICData::New(caller_function_, name_, args_descriptor_, DeoptId::kNone,
+ /*num_args_tested=*/1, ICData::kInstance);
+}
+
+ICDataPtr SwitchableCallHandler::NewICDataWithTarget(intptr_t cid,
+ const Function& target) {
+ GrowableArray<intptr_t> cids(1);
+ cids.Add(cid);
+ return ICData::NewWithCheck(caller_function_, name_, args_descriptor_,
+ DeoptId::kNone, /*num_args_tested=*/1,
+ ICData::kInstance, &cids, target);
+}
+
FunctionPtr SwitchableCallHandler::ResolveTargetFunction(const Object& data) {
switch (data.GetClassId()) {
case kUnlinkedCallCid: {