Revert "[vm, ffi] Remove special case for Fuchsia FFI callback thunks."

This reverts commit 61f45d66b2.
This reverts commit a0ab33ac52.
This reverts commit 68e2512ace.
This reverts commit fb732a570d.

TEST=ci
Bug: b/501539846
Cq-Include-Trybots: luci.dart.try:vm-fuchsia-release-x64-try,vm-fuchsia-release-arm64-try,vm-ffi-mac-debug-simarm64_arm64-try,vm-ffi-mac-release-simarm64_arm64-try
Change-Id: I7f27bb15bf1fcb26fe8793a043b7530ed99a02a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495480
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2026-04-14 12:22:48 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 19f129e946
commit df5cae97dc
21 changed files with 433 additions and 76 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
{
include: [
"//runtime/vm.shard.cml",
"//runtime/vm-jit.shard.cml",
],
program: {
binary: "exe.stripped/dartvm",
+1 -1
View File
@@ -4,7 +4,7 @@
{
include: [
"//runtime/vm.shard.cml",
"//runtime/vm-jit.shard.cml",
],
program: {
binary: "exe.stripped/run_vm_tests",
+16
View File
@@ -0,0 +1,16 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
{
include: [
"//runtime/vm.shard.cml",
],
use: [
{
protocol: [
"fuchsia.kernel.VmexResource",
],
},
]
}
-1
View File
@@ -31,7 +31,6 @@
"fuchsia.deprecatedtimezone.Timezone",
"fuchsia.inspect.InspectSink",
"fuchsia.intl.PropertyProvider",
"fuchsia.kernel.VmexResource",
"fuchsia.logger.LogSink",
"fuchsia.net.name.Lookup",
"fuchsia.posix.socket.Provider",
@@ -264,6 +264,13 @@ bool FlowGraphCompiler::CanOSRFunction() const {
!is_optimizing();
}
void FlowGraphCompiler::InsertBSSRelocation(BSS::Relocation reloc) {
const intptr_t offset = assembler()->InsertAlignedRelocation(reloc);
AddDescriptor(UntaggedPcDescriptors::kBSSRelocation, /*pc_offset=*/offset,
/*deopt_id=*/DeoptId::kNone, InstructionSource(),
/*try_index=*/-1);
}
bool FlowGraphCompiler::ForceSlowPathForStackOverflow() const {
#if !defined(PRODUCT)
if (FLAG_stacktrace_every > 0 || FLAG_deoptimize_every > 0 ||
@@ -478,6 +478,9 @@ class FlowGraphCompiler : public ValueObject {
bool CanOSRFunction() const;
bool is_optimizing() const { return is_optimizing_; }
void InsertBSSRelocation(BSS::Relocation reloc);
void LoadBSSEntry(BSS::Relocation relocation, Register dst, Register tmp);
// The function was fully intrinsified, so the body is unreachable.
//
// We still need to compile the body in unoptimized mode because the
@@ -1042,6 +1042,31 @@ void FlowGraphCompiler::EmitNativeLoad(Register dst,
}
}
void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ b(&skip_reloc);
InsertBSSRelocation(relocation);
__ Bind(&skip_reloc);
// For historical reasons, the PC on ARM points 8 bytes (two instructions)
// past the current instruction.
__ sub(tmp, PC,
compiler::Operand(Instr::kPCReadOffset + compiler::target::kWordSize));
// tmp holds the address of the relocation.
__ ldr(dst, compiler::Address(tmp));
// dst holds the relocation itself: tmp - bss_start.
// tmp = tmp + (bss_start - tmp) = bss_start
__ add(tmp, tmp, compiler::Operand(dst));
// tmp holds the start of the BSS section.
// Load the "get-thread" routine: *bss_start.
__ ldr(dst, compiler::Address(tmp));
}
#undef __
#define __ compiler_->assembler()->
@@ -1068,6 +1068,28 @@ void FlowGraphCompiler::EmitNativeLoad(Register dst,
}
}
void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ b(&skip_reloc);
InsertBSSRelocation(relocation);
__ Bind(&skip_reloc);
__ adr(tmp, compiler::Immediate(-compiler::target::kWordSize));
// tmp holds the address of the relocation.
__ ldr(dst, compiler::Address(tmp));
// dst holds the relocation itself: tmp - bss_start.
// tmp = tmp + (bss_start - tmp) = bss_start
__ add(tmp, tmp, compiler::Operand(dst));
// tmp holds the start of the BSS section.
// Load the "get-thread" routine: *bss_start.
__ ldr(dst, compiler::Address(tmp));
}
#undef __
#define __ compiler_->assembler()->
@@ -1141,6 +1141,29 @@ void FlowGraphCompiler::EmitNativeLoad(Register dst,
__ PopRegister(tmp);
}
void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ j(&skip_reloc, compiler::Assembler::kNearJump);
InsertBSSRelocation(relocation);
__ Bind(&skip_reloc);
__ auipc(tmp, 0);
__ addi(tmp, tmp, -compiler::target::kWordSize);
// tmp holds the address of the relocation.
__ lx(dst, compiler::Address(tmp));
// dst holds the relocation itself: tmp - bss_start.
// tmp = tmp + (bss_start - tmp) = bss_start
__ add(tmp, tmp, dst);
// tmp holds the start of the BSS section.
// Load the "get-thread" routine: *bss_start.
__ lx(dst, compiler::Address(tmp));
}
#undef __
#define __ compiler_->assembler()->
@@ -1072,6 +1072,32 @@ void FlowGraphCompiler::EmitNativeLoad(Register dst,
}
}
void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ jmp(&skip_reloc);
InsertBSSRelocation(relocation);
const intptr_t reloc_end = __ CodeSize();
__ Bind(&skip_reloc);
const intptr_t kLeaqLength = 7;
__ leaq(dst, compiler::Address::AddressRIPRelative(
-kLeaqLength - compiler::target::kWordSize));
ASSERT((__ CodeSize() - reloc_end) == kLeaqLength);
// dst holds the address of the relocation.
__ movq(tmp, compiler::Address(dst, 0));
// tmp holds the relocation itself: dst - bss_start.
// dst = dst + (bss_start - dst) = bss_start
__ addq(dst, tmp);
// dst holds the start of the BSS section.
// Load the routine.
__ movq(dst, compiler::Address(dst, 0));
}
#undef __
#define __ compiler_->assembler()->
+11
View File
@@ -2781,6 +2781,17 @@ void StubCodeCompiler::GenerateFfiAsyncCallbackSendStub() {
__ Ret();
}
void StubCodeCompiler::InsertBSSRelocation(BSS::Relocation reloc) {
ASSERT(pc_descriptors_list_ != nullptr);
const intptr_t pc_offset = assembler->InsertAlignedRelocation(reloc);
pc_descriptors_list_->AddDescriptor(
UntaggedPcDescriptors::kBSSRelocation, pc_offset,
/*deopt_id=*/DeoptId::kNone,
/*token_pos=*/TokenPosition::kNoSource,
/*try_index=*/-1,
/*yield_index=*/UntaggedPcDescriptors::kInvalidYieldIndex);
}
#if !defined(TARGET_ARCH_IA32)
static void GenerateSubtypeTestCacheLoopBody(Assembler* assembler,
int n,
+5
View File
@@ -238,6 +238,11 @@ class StubCodeCompiler {
intptr_t return_function_offset_in_object_store,
intptr_t return_stub_offset_in_thread);
void GenerateLoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp);
void InsertBSSRelocation(BSS::Relocation reloc);
void GenerateLoadFfiCallbackMetadataRuntimeFunction(uword function_index,
Register dst);
@@ -271,6 +271,31 @@ void StubCodeCompiler::GenerateFfiCallTrampolineStub() {
__ Breakpoint(); // Not implemented.
}
void StubCodeCompiler::GenerateLoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ b(&skip_reloc);
InsertBSSRelocation(relocation);
__ Bind(&skip_reloc);
// For historical reasons, the PC on ARM points 8 bytes (two instructions)
// past the current instruction.
__ sub(tmp, PC,
compiler::Operand(Instr::kPCReadOffset + compiler::target::kWordSize));
// tmp holds the address of the relocation.
__ ldr(dst, compiler::Address(tmp));
// dst holds the relocation itself: tmp - bss_start.
// tmp = tmp + (bss_start - tmp) = bss_start
__ add(tmp, tmp, compiler::Operand(dst));
// tmp holds the start of the BSS section.
// Load the "get-thread" routine: *bss_start.
__ ldr(dst, compiler::Address(tmp));
}
void StubCodeCompiler::GenerateLoadFfiCallbackMetadataRuntimeFunction(
uword function_index,
Register dst) {
@@ -434,6 +434,28 @@ void StubCodeCompiler::GenerateFfiCallTrampolineStub() {
__ Breakpoint(); // See ffi_trampolines_arm64.S
}
void StubCodeCompiler::GenerateLoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ b(&skip_reloc);
InsertBSSRelocation(relocation);
__ Bind(&skip_reloc);
__ adr(tmp, compiler::Immediate(-compiler::target::kWordSize));
// tmp holds the address of the relocation.
__ ldr(dst, compiler::Address(tmp));
// dst holds the relocation itself: tmp - bss_start.
// tmp = tmp + (bss_start - tmp) = bss_start
__ add(tmp, tmp, compiler::Operand(dst));
// tmp holds the start of the BSS section.
// Load the "get-thread" routine: *bss_start.
__ ldr(dst, compiler::Address(tmp));
}
void StubCodeCompiler::GenerateLoadFfiCallbackMetadataRuntimeFunction(
uword function_index,
Register dst) {
@@ -499,8 +521,23 @@ void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
__ mov(R0, R9);
__ mov(R1, SP);
#if defined(DART_TARGET_OS_FUCHSIA)
// TODO(https://dartbug.com/52579): Remove.
if (FLAG_precompiled_mode) {
GenerateLoadBSSEntry(BSS::Relocation::DLRT_GetFfiCallbackMetadata, R4,
R9);
} else {
Label call;
__ ldr(R4, Address::PC(2 * Instr::kInstrSize));
__ b(&call);
__ Emit64(reinterpret_cast<int64_t>(&DLRT_GetFfiCallbackMetadata));
__ Bind(&call);
}
#else
GenerateLoadFfiCallbackMetadataRuntimeFunction(
FfiCallbackMetadata::kGetFfiCallbackMetadata, R4);
#endif // defined(DART_TARGET_OS_FUCHSIA)
__ mov(CSP, SP);
__ blr(R4); // DLRT_GetFfiCallbackMetadata
__ mov(SP, CSP);
@@ -173,6 +173,13 @@ void StubCodeCompiler::GenerateExitSafepointStub() {
__ ret();
}
void StubCodeCompiler::GenerateLoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
// Only used in AOT.
__ Breakpoint();
}
// Calls a native function inside a safepoint.
//
// On entry:
@@ -283,6 +283,29 @@ void StubCodeCompiler::GenerateFfiCallTrampolineStub() {
__ Breakpoint(); // Not implemented.
}
void StubCodeCompiler::GenerateLoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ j(&skip_reloc, compiler::Assembler::kNearJump);
InsertBSSRelocation(relocation);
__ Bind(&skip_reloc);
__ auipc(tmp, 0);
__ addi(tmp, tmp, -compiler::target::kWordSize);
// tmp holds the address of the relocation.
__ lx(dst, compiler::Address(tmp));
// dst holds the relocation itself: tmp - bss_start.
// tmp = tmp + (bss_start - tmp) = bss_start
__ add(tmp, tmp, dst);
// tmp holds the start of the BSS section.
// Load the "get-thread" routine: *bss_start.
__ lx(dst, compiler::Address(tmp));
}
void StubCodeCompiler::GenerateLoadFfiCallbackMetadataRuntimeFunction(
uword function_index,
Register dst) {
@@ -354,10 +377,36 @@ void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
__ mv(A0, T1);
__ mv(A1, SP);
// Since DLRT_GetFfiCallbackMetadata can theoretically be loaded anywhere,
// we use the same trick as before to ensure a predictable instruction
// sequence.
#if defined(DART_TARGET_OS_FUCHSIA)
// TODO(https://dartbug.com/52579): Remove.
if (FLAG_precompiled_mode) {
GenerateLoadBSSEntry(BSS::Relocation::DLRT_GetFfiCallbackMetadata, T1,
T2);
} else {
const intptr_t kPCRelativeLoadOffset = 12;
intptr_t start = __ CodeSize();
__ auipc(T1, 0);
__ lx(T1, Address(T1, kPCRelativeLoadOffset));
Label call;
__ j(&call);
ASSERT_EQUAL(__ CodeSize() - start, kPCRelativeLoadOffset);
#if XLEN == 32
__ Emit32(reinterpret_cast<int32_t>(&DLRT_GetFfiCallbackMetadata));
#else
__ Emit64(reinterpret_cast<int64_t>(&DLRT_GetFfiCallbackMetadata));
#endif
__ Bind(&call);
}
#else
GenerateLoadFfiCallbackMetadataRuntimeFunction(
FfiCallbackMetadata::kGetFfiCallbackMetadata, T1);
__ jalr(T1);
#endif // defined(DART_TARGET_OS_FUCHSIA)
__ jalr(T1);
__ mv(THR, A0);
__ lx(T2, Address(SP, 0 * target::kWordSize)); // entry_point
__ lx(T3, Address(SP, 1 * target::kWordSize)); // is_tail
@@ -459,6 +459,32 @@ void StubCodeCompiler::GenerateFfiCallTrampolineStub() {
__ Ret();
}
void StubCodeCompiler::GenerateLoadBSSEntry(BSS::Relocation relocation,
Register dst,
Register tmp) {
compiler::Label skip_reloc;
__ jmp(&skip_reloc);
InsertBSSRelocation(relocation);
const intptr_t reloc_end = __ CodeSize();
__ Bind(&skip_reloc);
const intptr_t kLeaqLength = 7;
__ leaq(dst, compiler::Address::AddressRIPRelative(
-kLeaqLength - compiler::target::kWordSize));
ASSERT((__ CodeSize() - reloc_end) == kLeaqLength);
// dst holds the address of the relocation.
__ movq(tmp, compiler::Address(dst, 0));
// tmp holds the relocation itself: dst - bss_start.
// dst = dst + (bss_start - dst) = bss_start
__ addq(dst, tmp);
// dst holds the start of the BSS section.
// Load the routine.
__ movq(dst, compiler::Address(dst, 0));
}
void StubCodeCompiler::GenerateLoadFfiCallbackMetadataRuntimeFunction(
uword function_index,
Register dst) {
@@ -527,8 +553,20 @@ void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
__ movq(CallingConventions::kArg1Reg, RAX);
__ movq(CallingConventions::kArg2Reg, RSP);
#if defined(DART_TARGET_OS_FUCHSIA)
// TODO(https://dartbug.com/52579): Remove.
if (FLAG_precompiled_mode) {
GenerateLoadBSSEntry(BSS::Relocation::DLRT_GetFfiCallbackMetadata, RAX,
TMP);
} else {
__ movq(RAX, Immediate(
reinterpret_cast<int64_t>(DLRT_GetFfiCallbackMetadata)));
}
#else
GenerateLoadFfiCallbackMetadataRuntimeFunction(
FfiCallbackMetadata::kGetFfiCallbackMetadata, RAX);
#endif // defined(DART_TARGET_OS_FUCHSIA)
__ CallCFunction(RAX, /*restore_rsp=*/true);
__ movq(THR, RAX);
+104 -21
View File
@@ -29,26 +29,28 @@ void FfiCallbackMetadata::EnsureStubPageLocked() {
ASSERT_LESS_OR_EQUAL(VirtualMemory::PageSize(), kPageSize);
uword code_start, code_end, code_size;
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
uword code_start, code_end, page_start;
if (FLAG_use_simulator) {
code_start = reinterpret_cast<uword>(SimulatorFfiCallbackTrampoline);
code_end = reinterpret_cast<uword>(SimulatorFfiCallbackTrampolineEnd);
code_size = code_end - code_start;
page_start = code_start & ~(VirtualMemory::PageSize() - 1);
} else {
const Code& trampoline_code = StubCode::FfiCallbackTrampoline();
code_start = trampoline_code.EntryPoint();
code_end = code_start + trampoline_code.Size();
code_size = trampoline_code.Size();
page_start = code_start & ~(VirtualMemory::PageSize() - 1);
ASSERT_LESS_OR_EQUAL((code_start - page_start) + trampoline_code.Size(),
RXMappingSize());
}
#else
const Code& trampoline_code = StubCode::FfiCallbackTrampoline();
code_start = trampoline_code.EntryPoint();
code_end = code_start + trampoline_code.Size();
code_size = trampoline_code.Size();
#endif
const uword code_start = trampoline_code.EntryPoint();
const uword code_end = code_start + trampoline_code.Size();
const uword page_start = code_start & ~(VirtualMemory::PageSize() - 1);
ASSERT_LESS_OR_EQUAL((code_start - page_start) + code_size, RXMappingSize());
ASSERT_LESS_OR_EQUAL((code_start - page_start) + trampoline_code.Size(),
RXMappingSize());
#endif
// Stub page uses a tight (unaligned) bound for the end of the code area.
// Otherwise we can read past the end of the code area when doing DuplicateRX.
@@ -56,6 +58,32 @@ void FfiCallbackMetadata::EnsureStubPageLocked() {
code_end - page_start);
offset_of_first_trampoline_in_page_ = code_start - page_start;
#if defined(DART_TARGET_OS_FUCHSIA)
// On Fuchsia we can't currently duplicate pages, so use the first page of
// trampolines. Store the stub page's metadata in a separately allocated RW
// page.
// TODO(https://dartbug.com/52579): Remove.
original_metadata_page_ = VirtualMemory::AllocateAligned(
MappingSize(), MappingAlignment(), /*is_executable=*/false,
/*is_compressed=*/false, "FfiCallbackMetadata::TrampolinePage");
MetadataEntry* metadata_entry = reinterpret_cast<MetadataEntry*>(
original_metadata_page_->start() + MetadataOffset());
for (intptr_t i = 0; i < NumCallbackTrampolinesPerPage(); ++i) {
AddToFreeListLocked(&metadata_entry[i]);
}
#elif defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
if (FLAG_use_simulator) {
original_metadata_page_ = VirtualMemory::AllocateAligned(
MappingSize(), MappingAlignment(), /*is_executable=*/false,
/*is_compressed=*/false, "FfiCallbackMetadata::TrampolinePage");
MetadataEntry* metadata_entry = reinterpret_cast<MetadataEntry*>(
original_metadata_page_->start() + MetadataOffset());
for (intptr_t i = 0; i < NumCallbackTrampolinesPerPage(); ++i) {
AddToFreeListLocked(&metadata_entry[i]);
}
}
#endif // defined(DART_TARGET_OS_FUCHSIA)
}
FfiCallbackMetadata::~FfiCallbackMetadata() {
@@ -64,6 +92,12 @@ FfiCallbackMetadata::~FfiCallbackMetadata() {
for (intptr_t i = 0; i < trampoline_pages_.length(); ++i) {
delete trampoline_pages_[i];
}
#if defined(DART_TARGET_OS_FUCHSIA) || \
(defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64))
// TODO(https://dartbug.com/52579): Remove.
delete original_metadata_page_;
#endif // defined(DART_TARGET_OS_FUCHSIA)
}
void FfiCallbackMetadata::Init() {
@@ -97,6 +131,18 @@ void FfiCallbackMetadata::FillRuntimeFunction(VirtualMemory* page,
}
VirtualMemory* FfiCallbackMetadata::AllocateTrampolinePage() {
#if defined(DART_TARGET_OS_FUCHSIA)
// TODO(https://dartbug.com/52579): Remove.
UNREACHABLE();
return nullptr;
#else
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
if (FLAG_use_simulator) {
UNREACHABLE();
return nullptr;
}
#endif
#if defined(DART_HOST_OS_MACOS) && defined(DART_PRECOMPILED_RUNTIME)
const bool should_remap_stub_page = true;
#else
@@ -110,9 +156,6 @@ VirtualMemory* FfiCallbackMetadata::AllocateTrampolinePage() {
// codesigning violation if hardened runtime is enabled or we will simply
// not be able to execute trampoline code.
const bool is_executable = !should_remap_stub_page;
#elif defined(DART_HOST_OS_FUCHSIA)
// The initial allocation needs to be marked executable.
const bool is_executable = true;
#else
// On other operating systems we can simply flip RW->RX as necessary.
const bool is_executable = false;
@@ -167,14 +210,9 @@ VirtualMemory* FfiCallbackMetadata::AllocateTrampolinePage() {
#endif
return new_page;
#endif // defined(DART_TARGET_OS_FUCHSIA)
}
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
struct CallbackContext;
extern "C" void DoRedirectedFfiCallback(CallbackContext* ctxt,
uword trampoline);
#endif
void FfiCallbackMetadata::EnsureFreeListNotEmptyLocked() {
ASSERT(lock_.IsOwnedByCurrentThread());
EnsureStubPageLocked();
@@ -192,10 +230,6 @@ void FfiCallbackMetadata::EnsureFreeListNotEmptyLocked() {
// Fill in the runtime functions.
FillRuntimeFunction(new_page, kGetFfiCallbackMetadata,
reinterpret_cast<void*>(DLRT_GetFfiCallbackMetadata));
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
FillRuntimeFunction(new_page, kDoRedirectedFfiCallback,
reinterpret_cast<void*>(DoRedirectedFfiCallback));
#endif
// Add all the trampolines to the free list.
const intptr_t trampolines_per_page = NumCallbackTrampolinesPerPage();
@@ -399,12 +433,60 @@ FfiCallbackMetadata::Trampoline FfiCallbackMetadata::TrampolineOfMetadataEntry(
MetadataEntry* metadata_entries =
reinterpret_cast<MetadataEntry*>(start + MetadataOffset());
const uword index = metadata_entry - metadata_entries;
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
if (FLAG_use_simulator) {
return reinterpret_cast<uword>(SimulatorFfiCallbackTrampoline) +
index * kNativeCallbackTrampolineSize;
} else {
return start + offset_of_first_trampoline_in_page_ +
index * kNativeCallbackTrampolineSize;
}
#elif defined(DART_TARGET_OS_FUCHSIA)
return StubCode::FfiCallbackTrampoline().EntryPoint() +
index * kNativeCallbackTrampolineSize;
#else
return start + offset_of_first_trampoline_in_page_ +
index * kNativeCallbackTrampolineSize;
#endif
}
FfiCallbackMetadata::MetadataEntry*
FfiCallbackMetadata::MetadataEntryOfTrampoline(Trampoline trampoline) const {
#if defined(DART_TARGET_OS_FUCHSIA)
// On Fuchsia the metadata page is separate to the trampoline page.
// TODO(https://dartbug.com/52579): Remove.
const uword page_start =
Utils::RoundDown(trampoline - offset_of_first_trampoline_in_page_,
VirtualMemory::PageSize());
const uword index =
(trampoline - offset_of_first_trampoline_in_page_ - page_start) /
kNativeCallbackTrampolineSize;
ASSERT(index < NumCallbackTrampolinesPerPage());
MetadataEntry* metadata_etnry_table = reinterpret_cast<MetadataEntry*>(
original_metadata_page_->start() + MetadataOffset());
return metadata_etnry_table + index;
#elif defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
if (FLAG_use_simulator) {
const uword page_start =
Utils::RoundDown(trampoline - offset_of_first_trampoline_in_page_,
VirtualMemory::PageSize());
const uword index =
(trampoline - offset_of_first_trampoline_in_page_ - page_start) /
kNativeCallbackTrampolineSize;
ASSERT(index < NumCallbackTrampolinesPerPage());
MetadataEntry* metadata_etnry_table = reinterpret_cast<MetadataEntry*>(
original_metadata_page_->start() + MetadataOffset());
return metadata_etnry_table + index;
} else {
const uword start = MappingStart(trampoline);
MetadataEntry* metadata_entries =
reinterpret_cast<MetadataEntry*>(start + MetadataOffset());
const uword index =
(trampoline - start - offset_of_first_trampoline_in_page_) /
kNativeCallbackTrampolineSize;
return &metadata_entries[index];
}
#else
const uword start = MappingStart(trampoline);
MetadataEntry* metadata_entries =
reinterpret_cast<MetadataEntry*>(start + MetadataOffset());
@@ -412,6 +494,7 @@ FfiCallbackMetadata::MetadataEntryOfTrampoline(Trampoline trampoline) const {
(trampoline - start - offset_of_first_trampoline_in_page_) /
kNativeCallbackTrampolineSize;
return &metadata_entries[index];
#endif
}
FfiCallbackMetadata::Metadata
+21 -1
View File
@@ -62,7 +62,10 @@ class FfiCallbackMetadata {
enum RuntimeFunctions {
kGetFfiCallbackMetadata,
kDoRedirectedFfiCallback,
kExitTemporaryIsolate,
kExitIsolateGroupBoundIsolate,
kExitSyncCallbackTargetIsolate,
kExitSyncCallback,
kNumRuntimeFunctions,
};
@@ -284,6 +287,10 @@ class FfiCallbackMetadata {
static constexpr intptr_t kPageSize = 64 * KB;
#elif defined(DART_TARGET_OS_MACOS) && defined(TARGET_ARCH_ARM64)
static constexpr intptr_t kPageSize = 16 * KB;
#elif defined(DART_TARGET_OS_FUCHSIA)
// Fuchsia only gets one page, so make it big.
// TODO(https://dartbug.com/52579): Remove.
static constexpr intptr_t kPageSize = 64 * KB;
#else
static constexpr intptr_t kPageSize = 4 * KB;
#endif
@@ -394,6 +401,19 @@ class FfiCallbackMetadata {
MetadataEntry* free_list_head_ = nullptr;
MetadataEntry* free_list_tail_ = nullptr;
#if defined(DART_TARGET_OS_FUCHSIA) || \
(defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64))
// TODO(https://dartbug.com/52579): Remove.
// On Fuchsia, we cannot duplicate the page containing the trampoline stub
// unless we plumb through from the embedder the VMO handle that was used to
// load the VM isolate snapshot.
// On simulator FFI, SimulatorFfiCallbackTrampoline cannot be duplicated
// because it contains a PC-relative call. It would need to be replaced with
// something like normal stub's PC-relative loading to a corresponding data
// page, or if we can assume the initial-exec code model a TLS load.
VirtualMemory* original_metadata_page_ = nullptr;
#endif // defined(DART_TARGET_OS_FUCHSIA)
DISALLOW_COPY_AND_ASSIGN(FfiCallbackMetadata);
};
+11 -32
View File
@@ -6,12 +6,6 @@
// This is not written as VM stub because we need it be executable in contexts where we cannot JIT.
// (Alternatively, we could start requiring the VM snapshot to be provided in every mode.)
#if defined(__APPLE__)
#define LOCAL_SYMBOL(x) L##x
#else
#define LOCAL_SYMBOL(x) .L##x
#endif
#if defined(__aarch64__) && (defined(SIMULATOR_FFI) || (defined(DART_DYNAMIC_MODULES) && !defined(DART_PRECOMPILED_RUNTIME)))
.text
@@ -37,11 +31,11 @@ FfiCallTrampoline:
// Copy top frame from Dart stack to C stack
ldr x0, [x19, #0] // FfiCallArguments.stack_area
ldr x1, [x19, #8] // FfiCallArguments.stack_area_end
LOCAL_SYMBOL(copy1):
.Lcopy1:
ldp x2, x3, [x1, #-16]! // From stack_area
stp x2, x3, [sp, #-16]! // To C SP
cmp x1, x0
b.gt LOCAL_SYMBOL(copy1)
b.gt .Lcopy1
// Load the ABI argument registers. Note that Dart FFI does not support
// full 128-bit SIMD arguments, so we don't need to set the full V
@@ -98,11 +92,11 @@ SimulatorFfiCalloutTrampoline:
ldr x1, [x19, #24] // CalloutContext.simulator_frame_pointer
add x1, x1, 15 // Round up the frame pointer, since the Dart frame pointer
and x1, x1, ~15 // is not double-word aligned.
LOCAL_SYMBOL(copy2):
.Lcopy2:
ldp x2, x3, [x1, #-16]! // From Dart FP
stp x2, x3, [sp, #-16]! // To C SP
cmp x1, x0
b.gt LOCAL_SYMBOL(copy2)
b.gt .Lcopy2
// Load the ABI argument registers. Note that Dart FFI does not support
// full 128-bit SIMD arguments, so we don't need to set the full V
@@ -143,18 +137,12 @@ _SimulatorFfiCallbackTrampoline:
.type SimulatorFfiCallbackTrampoline, %function
SimulatorFfiCallbackTrampoline:
#endif
LOCAL_SYMBOL(start):
#if defined(__Fuchsia__)
.rept 483 // FfiCallbackMetadata::NumCallbackTrampolinesPerPage()
#elif defined(__APPLE__)
.rept 2019 // FfiCallbackMetadata::NumCallbackTrampolinesPerPage()
#else
.rept 8163 // FfiCallbackMetadata::NumCallbackTrampolinesPerPage()
#endif
// FfiCallbackMetadata::NumCallbackTrampolinesPerPage() == 8150
.rept 8150
adr x9, 0
b LOCAL_SYMBOL(body)
b .Lbody
.endr
LOCAL_SYMBOL(body):
.Lbody:
mov x10, sp
stp fp, lr, [sp, #-16]!
mov fp, sp
@@ -176,20 +164,11 @@ LOCAL_SYMBOL(body):
// Pass arguments registers and thunk address to the runtime.
mov x0, sp
mov x1, x9 // I.e., which callback.
adr x2, LOCAL_SYMBOL(start)
#if defined(__Fuchsia__)
and x2, x2, ~(0x1000-1) // FfiCallbackMetadata::kPageSize = 4k
add x2, x2, 0x2000
#elif defined(__APPLE__)
and x2, x2, ~(0x4000-1) // FfiCallbackMetadata::kPageSize = 16k
add x2, x2, 0x8000
#if defined(__APPLE__)
bl _DoRedirectedFfiCallback
#else
and x2, x2, ~(0x10000-1) // FfiCallbackMetadata::kPageSize = 64k
add x2, x2, 0x20000
bl DoRedirectedFfiCallback
#endif
ldr x2, [x2, #8] // FfiCallbackMetadata::kDoRedirectedFfiCallback
blr x2 // DoRedirectedFfiCallback
// Load ABI result registers.
ldp x0, x1, [sp, #0] // CallbackContext.integer_arguments[0]
-18
View File
@@ -1829,24 +1829,8 @@ struct CallbackContext {
uword sp;
};
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
extern "C" void DoRedirectedFfiCallback(CallbackContext* ctxt,
uword trampoline) {
// Assumptions in ffi_trampolines_arm64.S
COMPILE_ASSERT(sizeof(CallbackContext) == 144);
COMPILE_ASSERT(FfiCallbackMetadata::kDoRedirectedFfiCallback == 1);
#if defined(DART_TARGET_OS_FUCHSIA)
COMPILE_ASSERT(FfiCallbackMetadata::kPageSize == 4 * KB);
COMPILE_ASSERT(FfiCallbackMetadata::NumCallbackTrampolinesPerPage() == 483);
#elif defined(DART_TARGET_OS_MACOS)
COMPILE_ASSERT(FfiCallbackMetadata::kPageSize == 16 * KB);
COMPILE_ASSERT(FfiCallbackMetadata::NumCallbackTrampolinesPerPage() == 2019);
#else
COMPILE_ASSERT(FfiCallbackMetadata::kPageSize == 64 * KB);
COMPILE_ASSERT(FfiCallbackMetadata::NumCallbackTrampolinesPerPage() == 8163);
#endif
CallbackMetadata out;
Thread* thread = DLRT_GetFfiCallbackMetadata(trampoline, &out);
if (thread == nullptr) {
@@ -1860,8 +1844,6 @@ extern "C" void DoRedirectedFfiCallback(CallbackContext* ctxt,
sim->DoRedirectedFfiCallback(thread, ctxt, &out);
}
#endif // defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
// Compare FfiCallbackTrampolineStub.
void Simulator::DoRedirectedFfiCallback(Thread* thread,
CallbackContext* ctxt,