[vm/aot] Remove reverse PC lookup from switchable calls
This is a preparation for removal of Code objects.
Issue: https://github.com/dart-lang/sdk/issues/44852
TEST=ci
Change-Id: I9765945731c91fbdac647cc448d021238f129880
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182361
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 30828a1..9e1e3cb 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -86,8 +86,8 @@
const Code& target);
static ObjectPtr GetSwitchableCallDataAt(uword return_address,
const Code& caller_code);
- static CodePtr GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code);
+ static uword GetSwitchableCallTargetEntryAt(uword return_address,
+ const Code& caller_code);
static CodePtr GetNativeCallAt(uword return_address,
const Code& caller_code,
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 89de68a..0947b58 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -108,15 +108,15 @@
}
}
-CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCallPattern call(return_address, caller_code);
- return call.target();
+ return call.target_entry();
} else {
SwitchableCallPattern call(return_address, caller_code);
- return call.target();
+ return call.target_entry();
}
}
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index a1d4c4d..b7590db 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -144,15 +144,15 @@
}
}
-CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCallPattern call(return_address, caller_code);
- return call.target();
+ return call.target_entry();
} else {
SwitchableCallPattern call(return_address, caller_code);
- return call.target();
+ return call.target_entry();
}
}
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 3104115..08ce568 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -261,11 +261,11 @@
UNREACHABLE();
}
-CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
+ const Code& caller_code) {
// Switchable instance calls only generated for precompilation.
UNREACHABLE();
- return Code::null();
+ return 0;
}
ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index c916789..1ba005f 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -321,8 +321,9 @@
// No need to flush the instruction cache, since the code is not modified.
}
- CodePtr target() const {
- return static_cast<CodePtr>(object_pool_.ObjectAt(target_index()));
+ uword target_entry() const {
+ return Code::Handle(Code::RawCast(object_pool_.ObjectAt(target_index())))
+ .MonomorphicEntryPoint();
}
};
@@ -395,18 +396,7 @@
object_pool_.SetRawValueAt(target_index(), target.MonomorphicEntryPoint());
}
- CodePtr target() const {
- const uword pc = object_pool_.RawValueAt(target_index());
- CodePtr result = ReversePc::Lookup(IsolateGroup::Current(), pc);
- if (result != Code::null()) {
- return result;
- }
- result = ReversePc::Lookup(Dart::vm_isolate_group(), pc);
- if (result != Code::null()) {
- return result;
- }
- UNREACHABLE();
- }
+ uword target_entry() const { return object_pool_.RawValueAt(target_index()); }
};
CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
@@ -511,15 +501,15 @@
}
}
-CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCall call(return_address, caller_code);
- return call.target();
+ return call.target_entry();
} else {
SwitchableCall call(return_address, caller_code);
- return call.target();
+ return call.target_entry();
}
}
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 16bb992..c2b7014 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -292,9 +292,11 @@
ASSERT(reg == CODE_REG);
}
-CodePtr SwitchableCallPattern::target() const {
- return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
+uword SwitchableCallPattern::target_entry() const {
+ return Code::Handle(Code::RawCast(object_pool_.ObjectAt(target_pool_index_)))
+ .MonomorphicEntryPoint();
}
+
void SwitchableCallPattern::SetTarget(const Code& target) const {
ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
object_pool_.SetObjectAt(target_pool_index_, target);
@@ -316,17 +318,8 @@
ASSERT(reg == LINK_REGISTER);
}
-CodePtr BareSwitchableCallPattern::target() const {
- const uword pc = object_pool_.RawValueAt(target_pool_index_);
- CodePtr result = ReversePc::Lookup(IsolateGroup::Current(), pc);
- if (result != Code::null()) {
- return result;
- }
- result = ReversePc::Lookup(Dart::vm_isolate_group(), pc);
- if (result != Code::null()) {
- return result;
- }
- UNREACHABLE();
+uword BareSwitchableCallPattern::target_entry() const {
+ return object_pool_.RawValueAt(target_pool_index_);
}
void BareSwitchableCallPattern::SetTarget(const Code& target) const {
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 5fe9ab3..7b7b43b 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -153,7 +153,7 @@
public:
SwitchableCallPattern(uword pc, const Code& code);
- CodePtr target() const;
+ uword target_entry() const;
void SetTarget(const Code& target) const;
private:
@@ -168,7 +168,7 @@
public:
BareSwitchableCallPattern(uword pc, const Code& code);
- CodePtr target() const;
+ uword target_entry() const;
void SetTarget(const Code& target) const;
private:
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index e7a0d24..a38a07e 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -428,8 +428,9 @@
target_pool_index_ = pool_index + 1;
}
-CodePtr SwitchableCallPattern::target() const {
- return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
+uword SwitchableCallPattern::target_entry() const {
+ return Code::Handle(Code::RawCast(object_pool_.ObjectAt(target_pool_index_)))
+ .MonomorphicEntryPoint();
}
void SwitchableCallPattern::SetTarget(const Code& target) const {
@@ -454,17 +455,8 @@
target_pool_index_ = pool_index + 1;
}
-CodePtr BareSwitchableCallPattern::target() const {
- const uword pc = object_pool_.RawValueAt(target_pool_index_);
- CodePtr result = ReversePc::Lookup(IsolateGroup::Current(), pc);
- if (result != Code::null()) {
- return result;
- }
- result = ReversePc::Lookup(Dart::vm_isolate_group(), pc);
- if (result != Code::null()) {
- return result;
- }
- UNREACHABLE();
+uword BareSwitchableCallPattern::target_entry() const {
+ return object_pool_.RawValueAt(target_pool_index_);
}
void BareSwitchableCallPattern::SetTarget(const Code& target) const {
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 4a8f7e2..ae75539 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -163,7 +163,7 @@
public:
SwitchableCallPattern(uword pc, const Code& code);
- CodePtr target() const;
+ uword target_entry() const;
void SetTarget(const Code& target) const;
private:
@@ -178,7 +178,7 @@
public:
BareSwitchableCallPattern(uword pc, const Code& code);
- CodePtr target() const;
+ uword target_entry() const;
void SetTarget(const Code& target) const;
private:
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 2a7cbd5..2c31114 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1520,11 +1520,12 @@
private:
FunctionPtr ResolveTargetFunction(const Object& data);
- void HandleMiss(const Object& old_data,
- const Code& old_target,
- const Function& target_function);
#if defined(DART_PRECOMPILED_RUNTIME)
+ void HandleMissAOT(const Object& old_data,
+ uword old_entry,
+ const Function& target_function);
+
void DoUnlinkedCallAOT(const UnlinkedCall& unlinked,
const Function& target_function);
void DoMonomorphicMissAOT(const Object& data,
@@ -1538,6 +1539,10 @@
intptr_t* lower,
intptr_t* upper);
#else
+ void HandleMissJIT(const Object& old_data,
+ const Code& old_target,
+ const Function& target_function);
+
void DoMonomorphicMissJIT(const Object& data,
const Function& target_function);
void DoICDataMissJIT(const ICData& data,
@@ -2086,7 +2091,6 @@
const auto& target_function =
Function::Handle(zone_, ResolveTargetFunction(old_data));
- auto& code = Code::Handle(zone_);
auto& data = Object::Handle(zone_);
// We ensure any transition in a patchable calls are done in an atomic
@@ -2100,9 +2104,12 @@
#if defined(DART_PRECOMPILED_RUNTIME)
data =
CodePatcher::GetSwitchableCallDataAt(caller_frame_->pc(), caller_code_);
- DEBUG_ONLY(code = CodePatcher::GetSwitchableCallTargetAt(caller_frame_->pc(),
- caller_code_));
+ uword target_entry = 0;
+ DEBUG_ONLY(target_entry = CodePatcher::GetSwitchableCallTargetEntryAt(
+ caller_frame_->pc(), caller_code_));
+ HandleMissAOT(data, target_entry, target_function);
#else
+ auto& code = Code::Handle(zone_);
if (should_consider_patching()) {
code ^= CodePatcher::GetInstanceCallAt(caller_frame_->pc(), caller_code_,
&data);
@@ -2110,34 +2117,52 @@
ASSERT(old_data.IsICData() || old_data.IsMegamorphicCache());
data = old_data.ptr();
}
+ HandleMissJIT(data, code, target_function);
#endif
- HandleMiss(data, code, target_function);
}
-void PatchableCallHandler::HandleMiss(const Object& old_data,
- const Code& old_code,
- const Function& target_function) {
- switch (old_data.GetClassId()) {
#if defined(DART_PRECOMPILED_RUNTIME)
+
+void PatchableCallHandler::HandleMissAOT(const Object& old_data,
+ uword old_entry,
+ const Function& target_function) {
+ switch (old_data.GetClassId()) {
case kUnlinkedCallCid:
- ASSERT(old_code.ptr() == StubCode::SwitchableCallMiss().ptr());
+ ASSERT(old_entry ==
+ StubCode::SwitchableCallMiss().MonomorphicEntryPoint());
DoUnlinkedCallAOT(UnlinkedCall::Cast(old_data), target_function);
break;
case kMonomorphicSmiableCallCid:
- ASSERT(old_code.ptr() == StubCode::MonomorphicSmiableCheck().ptr());
+ ASSERT(old_entry ==
+ StubCode::MonomorphicSmiableCheck().MonomorphicEntryPoint());
FALL_THROUGH;
case kSmiCid:
DoMonomorphicMissAOT(old_data, target_function);
break;
case kSingleTargetCacheCid:
- ASSERT(old_code.ptr() == StubCode::SingleTargetCall().ptr());
+ ASSERT(old_entry == StubCode::SingleTargetCall().MonomorphicEntryPoint());
DoSingleTargetMissAOT(SingleTargetCache::Cast(old_data), target_function);
break;
case kICDataCid:
- ASSERT(old_code.ptr() == StubCode::ICCallThroughCode().ptr());
+ ASSERT(old_entry ==
+ StubCode::ICCallThroughCode().MonomorphicEntryPoint());
DoICDataMissAOT(ICData::Cast(old_data), target_function);
break;
+ case kMegamorphicCacheCid:
+ ASSERT(old_entry == StubCode::MegamorphicCall().MonomorphicEntryPoint());
+ DoMegamorphicMiss(MegamorphicCache::Cast(old_data), target_function);
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
#else
+
+void PatchableCallHandler::HandleMissJIT(const Object& old_data,
+ const Code& old_code,
+ const Function& target_function) {
+ switch (old_data.GetClassId()) {
case kArrayCid:
// ICData three-element array: Smi(receiver CID), Smi(count),
// Function(target). It is the Array from ICData::entries_.
@@ -2146,7 +2171,6 @@
case kICDataCid:
DoICDataMissJIT(ICData::Cast(old_data), old_code, target_function);
break;
-#endif // defined(DART_PRECOMPILED_RUNTIME)
case kMegamorphicCacheCid:
ASSERT(old_code.ptr() == StubCode::MegamorphicCall().ptr() ||
(old_code.IsNull() && !should_consider_patching()));
@@ -2156,6 +2180,7 @@
UNREACHABLE();
}
}
+#endif // defined(DART_PRECOMPILED_RUNTIME)
static void InlineCacheMissHandler(Thread* thread,
Zone* zone,