Commit 440bbbe7 authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

[Sampling profiler] Restore callee-save registers in V8 unwind

Restore the callee-save registers now provided in the V8 API when
unwinding. This is a necessary condition to support unwinds of
functions that use dynamic stack allocation, which is failure mode
1 in the corresponding bug.

Bug: 1122124
Change-Id: Ifb30bbdd9df343251a7c215e5a5fc140754ac216
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2500453Reviewed-by: default avatarEtienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822204}
parent 40acec4b
......@@ -8,6 +8,14 @@
#include <memory>
#include <utility>
#include "build/build_config.h"
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
// V8 requires the embedder to establish the architecture define.
#define V8_TARGET_ARCH_ARM 1
#include "v8/include/v8-unwinder-state.h"
#endif
namespace {
class V8Module : public base::ModuleCache::Module {
......@@ -76,6 +84,52 @@ v8::MemoryRange GetEmbeddedCodeRange(v8::Isolate* isolate) {
return range;
}
void CopyCalleeSavedRegisterFromRegisterContext(
const base::RegisterContext& register_context,
v8::CalleeSavedRegisters* callee_saved_registers) {
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
// ARM requires callee-saved registers to be restored:
// https://crbug.com/v8/10799.
DCHECK(callee_saved_registers);
callee_saved_registers->arm_r4 =
reinterpret_cast<void*>(register_context.arm_r4);
callee_saved_registers->arm_r5 =
reinterpret_cast<void*>(register_context.arm_r5);
callee_saved_registers->arm_r6 =
reinterpret_cast<void*>(register_context.arm_r6);
callee_saved_registers->arm_r7 =
reinterpret_cast<void*>(register_context.arm_r7);
callee_saved_registers->arm_r8 =
reinterpret_cast<void*>(register_context.arm_r8);
callee_saved_registers->arm_r9 =
reinterpret_cast<void*>(register_context.arm_r9);
callee_saved_registers->arm_r10 =
reinterpret_cast<void*>(register_context.arm_r10);
#endif
}
void CopyCalleeSavedRegisterToRegisterContext(
const v8::CalleeSavedRegisters* callee_saved_registers,
base::RegisterContext& register_context) {
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
DCHECK(callee_saved_registers);
register_context.arm_r4 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r4);
register_context.arm_r5 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r5);
register_context.arm_r6 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r6);
register_context.arm_r7 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r7);
register_context.arm_r8 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r8);
register_context.arm_r9 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r9);
register_context.arm_r10 =
reinterpret_cast<uintptr_t>(callee_saved_registers->arm_r10);
#endif
}
} // namespace
V8Unwinder::V8Unwinder(v8::Isolate* isolate)
......@@ -199,6 +253,9 @@ base::UnwindResult V8Unwinder::TryUnwind(
register_state.fp = reinterpret_cast<void*>(
base::RegisterContextFramePointer(thread_context));
CopyCalleeSavedRegisterFromRegisterContext(*thread_context,
register_state.callee_saved.get());
if (!v8::Unwinder::TryUnwindV8Frames(
js_entry_stubs_, code_ranges_.size(), code_ranges_.buffer(),
&register_state, reinterpret_cast<const void*>(stack_top))) {
......@@ -217,6 +274,9 @@ base::UnwindResult V8Unwinder::TryUnwind(
base::RegisterContextFramePointer(thread_context) =
reinterpret_cast<uintptr_t>(register_state.fp);
CopyCalleeSavedRegisterToRegisterContext(register_state.callee_saved.get(),
*thread_context);
stack->emplace_back(
base::RegisterContextInstructionPointer(thread_context),
module_cache->GetModuleForAddress(
......
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