Commit d0650ae1 authored by Pierre Langlois's avatar Pierre Langlois Committed by Commit Bot

[arm64][builtins] Allow simulator instructions in builtins.

Simulator-specific instructions are very useful, we can:

  - Place breakpoints that enable the simulator's interactive debugger, allowing
    us to see registers, the stack and print JS objects.

  - Enable and disable simulator tracing dynamically.

  - Call printf() directly, as the simulator cannot easily support its calling
    convention.

However these tools are not available when generating builtins. The reason is
that when cross-compiling, builtins are generated for real hardware but may
still run inside the simulator on the host if we have a custom snapshot. Using
the `v8_embed_script` GN option will do that for example but embedders may also
do this with the V8 API.

mksnapshot cannot tell the difference between generating code for a simulator
build and a cross-build. If we change this, we can allow us to use
simulator-specific features in builtins in simulator builds.

So in this patch we:

  - Introduce a --target_is_simulator mksnapshot flag to drive the
    enable_simulator_code Assembler option.

  - Make sure the assembler respect the option instead of the USE_SIMULATOR
    macro.


Change-Id: I7a7249f514427c1a2518a1af3679679596a72c7e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1991497Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Pierre Langlois <pierre.langlois@arm.com>
Cr-Commit-Position: refs/heads/master@{#65734}
parent a374cc97
......@@ -20,7 +20,7 @@ import("gni/v8.gni")
# Specifies if the target build is a simulator build. Comparing target cpu
# with v8 target cpu to not affect simulator builds for making cross-compile
# snapshots.
is_target_simulator = (target_cpu != v8_target_cpu && !v8_multi_arch_build) ||
target_is_simulator = (target_cpu != v8_target_cpu && !v8_multi_arch_build) ||
(current_cpu != v8_current_cpu && v8_multi_arch_build)
# For faster Windows builds. See https://crbug.com/v8/8475.
......@@ -170,7 +170,7 @@ declare_args() {
# site-isolation in Chrome and on simulator builds which test code generation
# on these platforms.
v8_untrusted_code_mitigations =
v8_current_cpu != "x86" && (is_android || is_target_simulator)
v8_current_cpu != "x86" && (is_android || target_is_simulator)
# Enable minor mark compact.
v8_enable_minor_mc = true
......@@ -542,7 +542,7 @@ config("toolchain") {
}
# Mips64el/mipsel simulators.
if (is_target_simulator &&
if (target_is_simulator &&
(v8_current_cpu == "mipsel" || v8_current_cpu == "mips64el")) {
defines += [ "_MIPS_TARGET_SIMULATOR" ]
}
......@@ -1291,6 +1291,13 @@ template("run_mksnapshot") {
rebase_path("$target_gen_dir/embedded${suffix}.S", root_build_dir),
]
# This is needed to distinguish between generating code for the simulator
# and cross-compiling. The latter may need to run code on the host with the
# simulator but cannot use simulator-specific instructions.
if (target_is_simulator) {
args += [ "--target_is_simulator" ]
}
args += invoker.args
outputs += [ "$target_gen_dir/embedded${suffix}.S" ]
......
......@@ -476,14 +476,7 @@ Operand MemOperand::OffsetAsOperand() const {
}
}
void Assembler::Unreachable() {
#ifdef USE_SIMULATOR
debug("UNREACHABLE", __LINE__, BREAK);
#else
// Crash by branching to 0. lr now points near the fault.
Emit(BLR | Rn(xzr));
#endif
}
void Assembler::Unreachable() { debug("UNREACHABLE", __LINE__, BREAK); }
Address Assembler::target_pointer_address_at(Address pc) {
Instruction* instr = reinterpret_cast<Instruction*>(pc);
......
......@@ -3654,7 +3654,6 @@ void Assembler::EmitStringData(const char* string) {
}
void Assembler::debug(const char* message, uint32_t code, Instr params) {
#ifdef USE_SIMULATOR
if (options().enable_simulator_code) {
// The arguments to the debug marker need to be contiguous in memory, so
// make sure we don't try to emit pools.
......@@ -3676,12 +3675,6 @@ void Assembler::debug(const char* message, uint32_t code, Instr params) {
return;
}
// Fall through if Serializer is enabled.
#else
// Make sure we haven't dynamically enabled simulator code when there is no
// simulator built in.
DCHECK(!options().enable_simulator_code);
#endif
if (params & BREAK) {
brk(0);
......
......@@ -3138,11 +3138,10 @@ void TurboAssembler::PrintfNoPreserve(const char* format,
}
void TurboAssembler::CallPrintf(int arg_count, const CPURegister* args) {
// A call to printf needs special handling for the simulator, since the system
// printf function will use a different instruction set and the procedure-call
// standard will not be compatible.
#ifdef USE_SIMULATOR
{
// A call to printf needs special handling for the simulator, since the system
// printf function will use a different instruction set and the procedure-call
// standard will not be compatible.
if (options().enable_simulator_code) {
InstructionAccurateScope scope(this, kPrintfLength / kInstrSize);
hlt(kImmExceptionIsPrintf);
dc32(arg_count); // kPrintfArgCountOffset
......@@ -3161,10 +3160,10 @@ void TurboAssembler::CallPrintf(int arg_count, const CPURegister* args) {
arg_pattern_list |= (arg_pattern << (kPrintfArgPatternBits * i));
}
dc32(arg_pattern_list); // kPrintfArgPatternListOffset
return;
}
#else
Call(ExternalReference::printf_function());
#endif
}
void TurboAssembler::Printf(const char* format, CPURegister arg0,
......
......@@ -58,9 +58,15 @@ AssemblerOptions AssemblerOptions::Default(Isolate* isolate) {
options.enable_root_array_delta_access =
!serializer && !generating_embedded_builtin;
#ifdef USE_SIMULATOR
// Don't generate simulator specific code if we are building a snapshot, which
// might be run on real hardware.
options.enable_simulator_code = !serializer;
// Even though the simulator is enabled, we may still need to generate code
// that may need to run on both the simulator and real hardware. For example,
// if we are cross-compiling and embedding a script into the snapshot, the
// script will need to run on the host causing the embedded builtins to run in
// the simulator. While the final cross-compiled V8 will not have a simulator.
// So here we enable simulator specific code if not generating the snapshot or
// if we are but we are targetting the simulator *only*.
options.enable_simulator_code = !serializer || FLAG_target_is_simulator;
#endif
options.inline_offheap_trampolines &= !generating_embedded_builtin;
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
......
......@@ -1332,6 +1332,10 @@ DEFINE_STRING(startup_blob, nullptr,
DEFINE_STRING(target_arch, nullptr,
"The mksnapshot target arch. (mksnapshot only)")
DEFINE_STRING(target_os, nullptr, "The mksnapshot target os. (mksnapshot only)")
DEFINE_BOOL(target_is_simulator, false,
"Instruct mksnapshot that the target is meant to run in the "
"simulator and it can generate simulator-specific instructions. "
"(mksnapshot only)")
//
// Minor mark compact collector flags.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment