mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:19:47 +00:00
[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>
This commit is contained in:
parent
5f78a23bb9
commit
d423a3cd7a
|
@ -86,7 +86,7 @@ class CodePatcher : public AllStatic {
|
|||
const Code& target);
|
||||
static ObjectPtr GetSwitchableCallDataAt(uword return_address,
|
||||
const Code& caller_code);
|
||||
static CodePtr GetSwitchableCallTargetAt(uword return_address,
|
||||
static uword GetSwitchableCallTargetEntryAt(uword return_address,
|
||||
const Code& caller_code);
|
||||
|
||||
static CodePtr GetNativeCallAt(uword return_address,
|
||||
|
|
|
@ -108,15 +108,15 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
|
|||
}
|
||||
}
|
||||
|
||||
CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,15 +144,15 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
|
|||
}
|
||||
}
|
||||
|
||||
CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -261,11 +261,11 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
|
||||
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,
|
||||
|
|
|
@ -321,8 +321,9 @@ class SwitchableCall : public SwitchableCallBase {
|
|||
// 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 @@ class BareSwitchableCall : public SwitchableCallBase {
|
|||
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 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
|
|||
}
|
||||
}
|
||||
|
||||
CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -292,9 +292,11 @@ SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
|
|||
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 @@ BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc, const Code& code)
|
|||
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 {
|
||||
|
|
|
@ -153,7 +153,7 @@ class SwitchableCallPattern : public SwitchableCallPatternBase {
|
|||
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 @@ class BareSwitchableCallPattern : public SwitchableCallPatternBase {
|
|||
public:
|
||||
BareSwitchableCallPattern(uword pc, const Code& code);
|
||||
|
||||
CodePtr target() const;
|
||||
uword target_entry() const;
|
||||
void SetTarget(const Code& target) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -428,8 +428,9 @@ SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
|
|||
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 @@ BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc, const Code& code)
|
|||
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 {
|
||||
|
|
|
@ -163,7 +163,7 @@ class SwitchableCallPattern : public SwitchableCallPatternBase {
|
|||
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 @@ class BareSwitchableCallPattern : public SwitchableCallPatternBase {
|
|||
public:
|
||||
BareSwitchableCallPattern(uword pc, const Code& code);
|
||||
|
||||
CodePtr target() const;
|
||||
uword target_entry() const;
|
||||
void SetTarget(const Code& target) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -1520,11 +1520,12 @@ class PatchableCallHandler {
|
|||
|
||||
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 @@ class PatchableCallHandler {
|
|||
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 @@ void PatchableCallHandler::ResolveSwitchAndReturn(const Object& old_data) {
|
|||
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 @@ void PatchableCallHandler::ResolveSwitchAndReturn(const Object& old_data) {
|
|||
#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 @@ void PatchableCallHandler::ResolveSwitchAndReturn(const Object& old_data) {
|
|||
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,
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
void PatchableCallHandler::HandleMissAOT(const Object& old_data,
|
||||
uword old_entry,
|
||||
const Function& target_function) {
|
||||
switch (old_data.GetClassId()) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
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 @@ void PatchableCallHandler::HandleMiss(const Object& old_data,
|
|||
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 @@ void PatchableCallHandler::HandleMiss(const Object& old_data,
|
|||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
static void InlineCacheMissHandler(Thread* thread,
|
||||
Zone* zone,
|
||||
|
|
Loading…
Reference in a new issue