[vm] Runtime option to not use the simulator for simarm64_arm64.
TEST=ci
Cq-Include-Trybots: luci.dart.try:vm-ffi-mac-debug-simarm64_arm64-try,vm-ffi-mac-release-simarm64_arm64-try
Change-Id: Id98d337ce16ba4b434b5c69016f01eec9b85f9d2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434982
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index e90b911..f7dea8a 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1429,8 +1429,10 @@
__ mov(CSP, SP);
#if defined(SIMULATOR_FFI)
- __ Emit(Instr::kSimulatorFfiRedirectInstruction);
- ASSERT(branch == R9);
+ if (FLAG_use_simulator) {
+ __ Emit(Instr::kSimulatorFfiRedirectInstruction);
+ ASSERT(branch == R9);
+ }
#endif
__ blr(branch);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 1ee528d..bed546c 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -417,7 +417,9 @@
#endif
#if defined(SIMULATOR_FFI)
- __ Emit(Instr::kSimulatorFfiRedirectInstruction);
+ if (FLAG_use_simulator) {
+ __ Emit(Instr::kSimulatorFfiRedirectInstruction);
+ }
#endif
__ blr(R9);
@@ -469,11 +471,6 @@
}
void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
-#if defined(USING_SIMULATOR) && !defined(DART_PRECOMPILER)
- // TODO(37299): FFI is not supported in SIMARM64.
- // See Simulator::DoDirectedFfiCallback.
- __ Breakpoint();
-#else
Label body;
// R9 is volatile and not used for passing any arguments.
@@ -705,7 +702,6 @@
__ Breakpoint();
}
#endif
-#endif // !defined(HOST_ARCH_ARM64)
}
void StubCodeCompiler::GenerateDispatchTableNullErrorStub() {
diff --git a/runtime/vm/cpu_arm64.cc b/runtime/vm/cpu_arm64.cc
index b64a2ee..d435bf1 100644
--- a/runtime/vm/cpu_arm64.cc
+++ b/runtime/vm/cpu_arm64.cc
@@ -10,7 +10,6 @@
#include "vm/cpuinfo.h"
-#if !defined(USING_SIMULATOR)
#if defined(DART_HOST_OS_FUCHSIA)
#include <zircon/syscalls.h>
#elif defined(DART_HOST_OS_MACOS) || defined(DART_HOST_OS_IOS)
@@ -18,14 +17,19 @@
#elif defined(DART_HOST_OS_WINDOWS)
#include <processthreadsapi.h>
#endif
-#endif
namespace dart {
void CPU::FlushICache(uword start, uword size) {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
-#elif !defined(USING_SIMULATOR)
+#else
+#if defined(USING_SIMULATOR)
+ if (FLAG_use_simulator) {
+ return;
+ }
+#endif
+
// Nothing to do. Flushing no instructions.
if (size == 0) {
return;
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 17d236c..9be9ccc 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -104,15 +104,20 @@
const uword stub = StubCode::InvokeDartCode().EntryPoint();
#if defined(USING_SIMULATOR)
- auto invoke = [&](uword entry_point, uword arguments_descriptor,
- uword arguments, Thread* thread) -> uword {
- return Simulator::Current()->Call(stub, entry_point, arguments_descriptor,
- arguments,
- reinterpret_cast<int64_t>(thread));
- };
-#else
- auto invoke = reinterpret_cast<invokestub>(stub);
+ if (FLAG_use_simulator) {
+ auto invoke = [&](uword entry_point, uword arguments_descriptor,
+ uword arguments, Thread* thread) -> uword {
+ return Simulator::Current()->Call(stub, entry_point, arguments_descriptor,
+ arguments,
+ reinterpret_cast<int64_t>(thread));
+ };
+ uword result =
+ invoke(entry_point, static_cast<uword>(arguments_descriptor.ptr()),
+ static_cast<uword>(arguments.ptr()), thread);
+ return static_cast<ObjectPtr>(result);
+ }
#endif
+ auto invoke = reinterpret_cast<invokestub>(stub);
uword result =
invoke(entry_point, static_cast<uword>(arguments_descriptor.ptr()),
static_cast<uword>(arguments.ptr()), thread);
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index d4ee65c..667fcdd 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -627,9 +627,12 @@
// exception object in the kExceptionObjectReg register and the stacktrace
// object (may be raw null) in the kStackTraceObjectReg register.
- Simulator::Current()->JumpToFrame(program_counter, stack_pointer,
- frame_pointer, thread);
-#else
+ if (FLAG_use_simulator) {
+ Simulator::Current()->JumpToFrame(program_counter, stack_pointer,
+ frame_pointer, thread);
+ UNREACHABLE();
+ }
+#endif
// Zero out HWASAN tags from the current stack pointer to the destination.
//
@@ -677,7 +680,6 @@
}
func(program_counter, stack_pointer, frame_pointer, thread);
-#endif
UNREACHABLE();
}
diff --git a/runtime/vm/ffi_callback_metadata.cc b/runtime/vm/ffi_callback_metadata.cc
index 879c967..4e78cd7 100644
--- a/runtime/vm/ffi_callback_metadata.cc
+++ b/runtime/vm/ffi_callback_metadata.cc
@@ -29,11 +29,19 @@
ASSERT_LESS_OR_EQUAL(VirtualMemory::PageSize(), kPageSize);
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
- const uword code_start =
- reinterpret_cast<uword>(SimulatorFfiCallbackTrampoline);
- const uword code_end =
- reinterpret_cast<uword>(SimulatorFfiCallbackTrampolineEnd);
- const uword page_start = code_start & ~(VirtualMemory::PageSize() - 1);
+ uword code_start, code_end, page_start;
+ if (FLAG_use_simulator) {
+ code_start = reinterpret_cast<uword>(SimulatorFfiCallbackTrampoline);
+ code_end = reinterpret_cast<uword>(SimulatorFfiCallbackTrampolineEnd);
+ 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();
+ 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();
const uword code_start = trampoline_code.EntryPoint();
@@ -50,8 +58,7 @@
offset_of_first_trampoline_in_page_ = code_start - page_start;
-#if defined(DART_TARGET_OS_FUCHSIA) || \
- (defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64))
+#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.
@@ -64,6 +71,17 @@
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)
}
@@ -112,12 +130,17 @@
}
VirtualMemory* FfiCallbackMetadata::AllocateTrampolinePage() {
-#if defined(DART_TARGET_OS_FUCHSIA) || \
- (defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64))
+#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;
@@ -413,8 +436,13 @@
reinterpret_cast<MetadataEntry*>(start + MetadataOffset());
const uword index = metadata_entry - metadata_entries;
#if defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64)
- return reinterpret_cast<uword>(SimulatorFfiCallbackTrampoline) +
- index * kNativeCallbackTrampolineSize;
+ 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;
@@ -426,8 +454,7 @@
FfiCallbackMetadata::MetadataEntry*
FfiCallbackMetadata::MetadataEntryOfTrampoline(Trampoline trampoline) const {
-#if defined(DART_TARGET_OS_FUCHSIA) || \
- (defined(SIMULATOR_FFI) && defined(HOST_ARCH_ARM64))
+#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 =
@@ -440,6 +467,27 @@
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 =
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index d560266..b90b3e1 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -249,6 +249,7 @@
"Throw API error on invalid member access through native API. See " \
"entry_point_pragma.md") \
C(branch_coverage, false, false, bool, false, "Enable branch coverage") \
- C(coverage, false, false, bool, true, "Enable coverage")
+ C(coverage, false, false, bool, true, "Enable coverage") \
+ P(use_simulator, bool, true, "Use simulator if available")
#endif // RUNTIME_VM_FLAG_LIST_H_
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index eba30df..ff78062 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -120,9 +120,11 @@
uword NativeEntry::BootstrapNativeCallWrapperEntry() {
uword entry = reinterpret_cast<uword>(DRT_BootstrapNativeCall);
#if defined(USING_SIMULATOR)
- entry = Simulator::RedirectExternalReference(
- entry, Simulator::kNativeCallWrapper,
- NativeEntry::kNumCallWrapperArguments);
+ if (FLAG_use_simulator) {
+ entry = Simulator::RedirectExternalReference(
+ entry, Simulator::kNativeCallWrapper,
+ NativeEntry::kNumCallWrapperArguments);
+ }
#endif
return entry;
}
@@ -164,9 +166,11 @@
uword NativeEntry::NoScopeNativeCallWrapperEntry() {
uword entry = reinterpret_cast<uword>(DRT_NoScopeNativeCall);
#if defined(USING_SIMULATOR)
- entry = Simulator::RedirectExternalReference(
- entry, Simulator::kNativeCallWrapper,
- NativeEntry::kNumCallWrapperArguments);
+ if (FLAG_use_simulator) {
+ entry = Simulator::RedirectExternalReference(
+ entry, Simulator::kNativeCallWrapper,
+ NativeEntry::kNumCallWrapperArguments);
+ }
#endif
return entry;
}
@@ -195,9 +199,11 @@
uword NativeEntry::AutoScopeNativeCallWrapperEntry() {
uword entry = reinterpret_cast<uword>(DRT_AutoScopeNativeCall);
#if defined(USING_SIMULATOR)
- entry = Simulator::RedirectExternalReference(
- entry, Simulator::kNativeCallWrapper,
- NativeEntry::kNumCallWrapperArguments);
+ if (FLAG_use_simulator) {
+ entry = Simulator::RedirectExternalReference(
+ entry, Simulator::kNativeCallWrapper,
+ NativeEntry::kNumCallWrapperArguments);
+ }
#endif
return entry;
}
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 2961c45..cc9c00b 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -365,7 +365,7 @@
#if defined(USING_SIMULATOR)
const bool use_simulator_stack_bounds =
- thread != nullptr && thread->IsExecutingDartCode();
+ FLAG_use_simulator && thread != nullptr && thread->IsExecutingDartCode();
if (use_simulator_stack_bounds) {
Isolate* isolate = thread->isolate();
ASSERT(isolate != nullptr);
@@ -1253,9 +1253,11 @@
// When running in the simulator, the runtime entry function address
// (stored as the vm tag) is the address of a redirect function.
// Attempt to find the real runtime entry function address and use that.
- uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag);
- if (redirect_vm_tag != 0) {
- vm_tag = redirect_vm_tag;
+ if (FLAG_use_simulator) {
+ uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag);
+ if (redirect_vm_tag != 0) {
+ vm_tag = redirect_vm_tag;
+ }
}
#endif
sample->set_vm_tag(vm_tag);
@@ -1388,18 +1390,19 @@
uintptr_t fp = state.fp;
uintptr_t pc = state.pc;
uintptr_t lr = state.lr;
-#if defined(USING_SIMULATOR)
- Simulator* simulator = nullptr;
-#endif
if (in_dart_code) {
-// If we're in Dart code, use the Dart stack pointer.
+ // If we're in Dart code, use the Dart stack pointer.
#if defined(USING_SIMULATOR)
- simulator = isolate->simulator();
- sp = simulator->get_register(SPREG);
- fp = simulator->get_register(FPREG);
- pc = simulator->get_pc();
- lr = simulator->get_lr();
+ if (FLAG_use_simulator) {
+ Simulator* simulator = isolate->simulator();
+ sp = simulator->get_register(SPREG);
+ fp = simulator->get_register(FPREG);
+ pc = simulator->get_pc();
+ lr = simulator->get_lr();
+ } else {
+ sp = state.dsp;
+ }
#else
sp = state.dsp;
#endif
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 306f0e3..88cf909 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -124,17 +124,20 @@
// into the runtime system.
uword entry = reinterpret_cast<uword>(function());
#if defined(USING_SIMULATOR)
- // Redirection to leaf runtime calls supports a maximum of 4 arguments passed
- // in registers (maximum 2 double arguments for leaf float runtime calls).
- ASSERT(argument_count() >= 0);
- ASSERT(!is_leaf() || (!is_float() && (argument_count() <= 4)) ||
- (argument_count() <= 2));
- Simulator::CallKind call_kind =
- is_leaf() ? (is_float() ? Simulator::kLeafFloatRuntimeCall
- : Simulator::kLeafRuntimeCall)
- : Simulator::kRuntimeCall;
- entry =
- Simulator::RedirectExternalReference(entry, call_kind, argument_count());
+ if (FLAG_use_simulator) {
+ // Redirection to leaf runtime calls supports a maximum of 4 arguments
+ // passed in registers (maximum 2 double arguments for leaf float runtime
+ // calls).
+ ASSERT(argument_count() >= 0);
+ ASSERT(!is_leaf() || (!is_float() && (argument_count() <= 4)) ||
+ (argument_count() <= 2));
+ Simulator::CallKind call_kind =
+ is_leaf() ? (is_float() ? Simulator::kLeafFloatRuntimeCall
+ : Simulator::kLeafRuntimeCall)
+ : Simulator::kRuntimeCall;
+ entry = Simulator::RedirectExternalReference(entry, call_kind,
+ argument_count());
+ }
#endif
return entry;
}
@@ -152,7 +155,7 @@
#if defined(USING_SIMULATOR)
#define CHECK_SIMULATOR_STACK_OVERFLOW() \
- if (!OSThread::Current()->HasStackHeadroom()) { \
+ if (FLAG_use_simulator && !OSThread::Current()->HasStackHeadroom()) { \
Exceptions::ThrowStackOverflow(); \
}
#else
@@ -3486,16 +3489,17 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
DEFINE_RUNTIME_ENTRY(InterruptOrStackOverflow, 0) {
-#if defined(USING_SIMULATOR)
- uword stack_pos = Simulator::Current()->get_sp();
- // If simulator was never called it may return 0 as a value of SPREG.
- if (stack_pos == 0) {
- // Use any reasonable value which would not be treated
- // as stack overflow.
- stack_pos = thread->saved_stack_limit();
- }
-#else
uword stack_pos = OSThread::GetCurrentStackPointer();
+#if defined(USING_SIMULATOR)
+ if (FLAG_use_simulator) {
+ stack_pos = Simulator::Current()->get_sp();
+ // If simulator was never called it may return 0 as a value of SPREG.
+ if (stack_pos == 0) {
+ // Use any reasonable value which would not be treated
+ // as stack overflow.
+ stack_pos = thread->saved_stack_limit();
+ }
+ }
#endif
// Always clear the stack overflow flags. They are meant for this
// particular stack overflow runtime call and are not meant to
@@ -4381,8 +4385,10 @@
#if defined(DART_DYNAMIC_MODULES)
uword entry = reinterpret_cast<uword>(InterpretCall);
#if defined(USING_SIMULATOR)
- entry = Simulator::RedirectExternalReference(entry,
- Simulator::kLeafRuntimeCall, 5);
+ if (FLAG_use_simulator) {
+ entry = Simulator::RedirectExternalReference(
+ entry, Simulator::kLeafRuntimeCall, 5);
+ }
#endif
return entry;
#else
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 1178afa..07c5646 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -533,7 +533,11 @@
ResumeThreadInternal(thread);
#if defined(USING_SIMULATOR)
- thread->SetStackLimit(Simulator::Current()->overflow_stack_limit());
+ if (FLAG_use_simulator) {
+ thread->SetStackLimit(Simulator::Current()->overflow_stack_limit());
+ } else {
+ thread->SetStackLimit(OSThread::Current()->overflow_stack_limit());
+ }
#else
thread->SetStackLimit(OSThread::Current()->overflow_stack_limit());
#endif
@@ -583,7 +587,11 @@
if (Dart::vm_isolate() != nullptr &&
thread->isolate() != Dart::vm_isolate()) {
#if defined(USING_SIMULATOR)
- thread->SetStackLimit(Simulator::Current()->overflow_stack_limit());
+ if (FLAG_use_simulator) {
+ thread->SetStackLimit(Simulator::Current()->overflow_stack_limit());
+ } else {
+ thread->SetStackLimit(OSThread::Current()->overflow_stack_limit());
+ }
#else
thread->SetStackLimit(OSThread::Current()->overflow_stack_limit());
#endif
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index b8a6afe..431dbff 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -297,7 +297,7 @@
"builder-tag": "ffi"
}
},
- "vm-(linux|mac|win|android|fuchsia)-(debug|product|release)-(ia32|x64|x64c|arm|arm64|arm64c|simarm|simarm64|simarm64_arm64|simriscv32|simriscv64)": {
+ "vm-(linux|mac|win|android|fuchsia)-(debug|product|release)-(ia32|x64|x64c|arm|arm64|arm64c|simarm|simarm64|simriscv32|simriscv64)": {
"options": {}
},
"vm-checked-(linux|mac|win|fuchsia)-(debug|product|release)-(ia32|x64|x64c|arm64|arm64c|simarm|simarm64|simriscv32|simriscv64)": {
@@ -348,6 +348,26 @@
"gen-snapshot-format" : "elf"
}
},
+ "vm-linux-(debug|product|release)-simarm64_arm64": {
+ "options": {
+ "vm-options": ["--use_simulator=true"], "use-qemu": true
+ }
+ },
+ "vm-linux-(debug|product|release)-simarm64_arm64-nosim": {
+ "options": {
+ "vm-options": ["--use_simulator=false"], "use-qemu": true
+ }
+ },
+ "vm-mac-(debug|product|release)-simarm64_arm64": {
+ "options": {
+ "vm-options": ["--use_simulator=true"]
+ }
+ },
+ "vm-mac-(debug|product|release)-simarm64_arm64-nosim": {
+ "options": {
+ "vm-options": ["--use_simulator=false"]
+ }
+ },
"dart2js-(linux|win)-chrome": {
"options": {
"use-sdk": true
@@ -814,6 +834,13 @@
"-nvm-${system}-${mode}-${arch}",
"ffi"
]
+ },
+ {
+ "name": "vm ffi tests",
+ "arguments": [
+ "-nvm-${system}-${mode}-${arch}-nosim",
+ "ffi"
+ ]
}
]
},