PPC/s390: enable --perf-prof on PPC and S390

Change-Id: I88adc527fea64c8ab6e9b32cfd8d40927e78da9a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1874087
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Junliang Yan <jyan@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#64931}
This commit is contained in:
Junliang Yan 2019-11-07 09:57:07 -05:00 committed by Commit Bot
parent 3ee5dbc0ca
commit b6ef2517aa
14 changed files with 559 additions and 30 deletions

View File

@ -3160,9 +3160,12 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/ppc/instruction-codes-ppc.h",
"src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
"src/compiler/backend/ppc/instruction-selector-ppc.cc",
"src/compiler/backend/ppc/unwinding-info-writer-ppc.cc",
"src/compiler/backend/ppc/unwinding-info-writer-ppc.h",
"src/debug/ppc/debug-ppc.cc",
"src/deoptimizer/ppc/deoptimizer-ppc.cc",
"src/diagnostics/ppc/disasm-ppc.cc",
"src/diagnostics/ppc/eh-frame-ppc.cc",
"src/execution/ppc/frame-constants-ppc.cc",
"src/execution/ppc/frame-constants-ppc.h",
"src/execution/ppc/simulator-ppc.cc",
@ -3187,9 +3190,12 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/s390/instruction-codes-s390.h",
"src/compiler/backend/s390/instruction-scheduler-s390.cc",
"src/compiler/backend/s390/instruction-selector-s390.cc",
"src/compiler/backend/s390/unwinding-info-writer-s390.cc",
"src/compiler/backend/s390/unwinding-info-writer-s390.h",
"src/debug/s390/debug-s390.cc",
"src/deoptimizer/s390/deoptimizer-s390.cc",
"src/diagnostics/s390/disasm-s390.cc",
"src/diagnostics/s390/eh-frame-s390.cc",
"src/execution/s390/frame-constants-s390.cc",
"src/execution/s390/frame-constants-s390.h",
"src/execution/s390/simulator-s390.cc",

View File

@ -2992,4 +2992,9 @@ class DoubleRegisters {
} // namespace internal
} // namespace v8
static constexpr int kR0DwarfCode = 0;
static constexpr int kFpDwarfCode = 31; // frame-pointer
static constexpr int kLrDwarfCode = 65; // return-address(lr)
static constexpr int kSpDwarfCode = 1; // stack-pointer (sp)
#endif // V8_CODEGEN_PPC_CONSTANTS_PPC_H_

View File

@ -129,7 +129,8 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
public:
OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode, StubCallMode stub_mode)
RecordWriteMode mode, StubCallMode stub_mode,
UnwindingInfoWriter* unwinding_info_writer)
: OutOfLineCode(gen),
object_(object),
offset_(offset),
@ -140,11 +141,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {}
OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode, StubCallMode stub_mode)
RecordWriteMode mode, StubCallMode stub_mode,
UnwindingInfoWriter* unwinding_info_writer)
: OutOfLineCode(gen),
object_(object),
offset_(no_reg),
@ -155,6 +158,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {}
void Generate() final {
@ -180,6 +184,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore lr if the frame was elided.
__ mflr(scratch0_);
__ Push(scratch0_);
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset());
}
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
__ CallEphemeronKeyBarrier(object_, scratch1_, save_fp_mode);
@ -194,6 +199,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore lr if the frame was elided.
__ Pop(scratch0_);
__ mtlr(scratch0_);
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
}
}
@ -207,6 +213,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
RecordWriteMode const mode_;
StubCallMode stub_mode_;
bool must_save_lr_;
UnwindingInfoWriter* const unwinding_info_writer_;
Zone* zone_;
};
@ -675,6 +682,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, Instruction* instr,
void CodeGenerator::AssembleDeconstructFrame() {
__ LeaveFrame(StackFrame::MANUAL);
unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset());
}
void CodeGenerator::AssemblePrepareTailCall() {
@ -1182,16 +1190,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingModeField::decode(instr->opcode());
if (addressing_mode == kMode_MRI) {
int32_t offset = i.InputInt32(1);
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
ool = new (zone()) OutOfLineRecordWrite(
this, object, offset, value, scratch0, scratch1, mode,
DetermineStubCallMode(), &unwinding_info_writer_);
__ StoreP(value, MemOperand(object, offset));
} else {
DCHECK_EQ(kMode_MRR, addressing_mode);
Register offset(i.InputRegister(1));
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
ool = new (zone()) OutOfLineRecordWrite(
this, object, offset, value, scratch0, scratch1, mode,
DetermineStubCallMode(), &unwinding_info_writer_);
__ StorePX(value, MemOperand(object, offset));
}
__ CheckPageFlag(object, scratch0,
@ -2407,6 +2415,7 @@ void CodeGenerator::AssembleConstructFrame() {
}
}
}
unwinding_info_writer_.MarkFrameConstructed(__ pc_offset());
}
int required_slots =
@ -2517,6 +2526,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
__ MultiPopDoubles(double_saves);
}
PPCOperandConverter g(this, nullptr);
unwinding_info_writer_.MarkBlockWillExit();
if (call_descriptor->IsCFunctionCall()) {
AssembleDeconstructFrame();

View File

@ -0,0 +1,105 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/backend/ppc/unwinding-info-writer-ppc.h"
#include "src/compiler/backend/instruction.h"
namespace v8 {
namespace internal {
namespace compiler {
void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset,
const InstructionBlock* block) {
if (!enabled()) return;
block_will_exit_ = false;
DCHECK_LT(block->rpo_number().ToInt(),
static_cast<int>(block_initial_states_.size()));
const BlockInitialState* initial_state =
block_initial_states_[block->rpo_number().ToInt()];
if (!initial_state) return;
if (initial_state->saved_lr_ != saved_lr_) {
eh_frame_writer_.AdvanceLocation(pc_offset);
if (initial_state->saved_lr_) {
eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode,
kSystemPointerSize);
eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
} else {
eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
}
saved_lr_ = initial_state->saved_lr_;
}
}
void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
if (!enabled() || block_will_exit_) return;
for (const RpoNumber& successor : block->successors()) {
int successor_index = successor.ToInt();
DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
const BlockInitialState* existing_state =
block_initial_states_[successor_index];
// If we already had an entry for this BB, check that the values are the
// same we are trying to insert.
if (existing_state) {
DCHECK_EQ(existing_state->saved_lr_, saved_lr_);
} else {
block_initial_states_[successor_index] =
new (zone_) BlockInitialState(saved_lr_);
}
}
}
void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) {
if (!enabled()) return;
// Regardless of the type of frame constructed, the relevant part of the
// layout is always the one in the diagram:
//
// | .... | higher addresses
// +----------+ ^
// | LR | | |
// +----------+ | |
// | saved FP | | |
// +----------+ <-- FP v
// | .... | stack growth
//
// The LR is pushed on the stack, and we can record this fact at the end of
// the construction, since the LR itself is not modified in the process.
eh_frame_writer_.AdvanceLocation(at_pc);
eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode,
kSystemPointerSize);
eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
saved_lr_ = true;
}
void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) {
if (!enabled()) return;
// The lr is restored by the last operation in LeaveFrame().
eh_frame_writer_.AdvanceLocation(at_pc);
eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
saved_lr_ = false;
}
void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) {
if (!enabled()) return;
eh_frame_writer_.AdvanceLocation(pc_offset);
eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0);
eh_frame_writer_.RecordRegisterSavedToStack(r30, 0);
}
void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) {
if (!enabled()) return;
eh_frame_writer_.AdvanceLocation(pc_offset);
eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0);
eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,73 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_BACKEND_PPC_UNWINDING_INFO_WRITER_PPC_H_
#define V8_COMPILER_BACKEND_PPC_UNWINDING_INFO_WRITER_PPC_H_
#include "src/diagnostics/eh-frame.h"
#include "src/flags/flags.h"
namespace v8 {
namespace internal {
namespace compiler {
class InstructionBlock;
class UnwindingInfoWriter {
public:
explicit UnwindingInfoWriter(Zone* zone)
: zone_(zone),
eh_frame_writer_(zone),
saved_lr_(false),
block_will_exit_(false),
block_initial_states_(zone) {
if (enabled()) eh_frame_writer_.Initialize();
}
void SetNumberOfInstructionBlocks(int number) {
if (enabled()) block_initial_states_.resize(number);
}
void BeginInstructionBlock(int pc_offset, const InstructionBlock* block);
void EndInstructionBlock(const InstructionBlock* block);
void MarkLinkRegisterOnTopOfStack(int pc_offset);
void MarkPopLinkRegisterFromTopOfStack(int pc_offset);
void MarkFrameConstructed(int at_pc);
void MarkFrameDeconstructed(int at_pc);
void MarkBlockWillExit() { block_will_exit_ = true; }
void Finish(int code_size) {
if (enabled()) eh_frame_writer_.Finish(code_size);
}
EhFrameWriter* eh_frame_writer() {
return enabled() ? &eh_frame_writer_ : nullptr;
}
private:
bool enabled() const { return FLAG_perf_prof_unwinding_info; }
class BlockInitialState : public ZoneObject {
public:
explicit BlockInitialState(bool saved_lr) : saved_lr_(saved_lr) {}
bool saved_lr_;
};
Zone* zone_;
EhFrameWriter eh_frame_writer_;
bool saved_lr_;
bool block_will_exit_;
ZoneVector<const BlockInitialState*> block_initial_states_;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_BACKEND_PPC_UNWINDING_INFO_WRITER_PPC_H_

View File

@ -168,7 +168,8 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
public:
OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode, StubCallMode stub_mode)
RecordWriteMode mode, StubCallMode stub_mode,
UnwindingInfoWriter* unwinding_info_writer)
: OutOfLineCode(gen),
object_(object),
offset_(offset),
@ -179,11 +180,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {}
OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode, StubCallMode stub_mode)
RecordWriteMode mode, StubCallMode stub_mode,
UnwindingInfoWriter* unwinding_info_writer)
: OutOfLineCode(gen),
object_(object),
offset_(no_reg),
@ -194,6 +197,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {}
void Generate() final {
@ -217,6 +221,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
if (must_save_lr_) {
// We need to save and restore r14 if the frame was elided.
__ Push(r14);
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset());
}
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
__ CallEphemeronKeyBarrier(object_, scratch1_, save_fp_mode);
@ -230,6 +235,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
if (must_save_lr_) {
// We need to save and restore r14 if the frame was elided.
__ Pop(r14);
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
}
}
@ -243,6 +249,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
RecordWriteMode const mode_;
StubCallMode stub_mode_;
bool must_save_lr_;
UnwindingInfoWriter* const unwinding_info_writer_;
Zone* zone_;
};
@ -1164,6 +1171,7 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) {
void CodeGenerator::AssembleDeconstructFrame() {
__ LeaveFrame(StackFrame::MANUAL);
unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset());
}
void CodeGenerator::AssemblePrepareTailCall() {
@ -1633,16 +1641,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingModeField::decode(instr->opcode());
if (addressing_mode == kMode_MRI) {
int32_t offset = i.InputInt32(1);
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
ool = new (zone()) OutOfLineRecordWrite(
this, object, offset, value, scratch0, scratch1, mode,
DetermineStubCallMode(), &unwinding_info_writer_);
__ StoreP(value, MemOperand(object, offset));
} else {
DCHECK_EQ(kMode_MRR, addressing_mode);
Register offset(i.InputRegister(1));
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
ool = new (zone()) OutOfLineRecordWrite(
this, object, offset, value, scratch0, scratch1, mode,
DetermineStubCallMode(), &unwinding_info_writer_);
__ StoreP(value, MemOperand(object, offset));
}
__ CheckPageFlag(object, scratch0,
@ -3113,6 +3121,7 @@ void CodeGenerator::AssembleConstructFrame() {
}
}
}
unwinding_info_writer_.MarkFrameConstructed(__ pc_offset());
}
int required_slots =
@ -3217,6 +3226,8 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
__ MultiPopDoubles(double_saves);
}
unwinding_info_writer_.MarkBlockWillExit();
S390OperandConverter g(this, nullptr);
if (call_descriptor->IsCFunctionCall()) {
AssembleDeconstructFrame();

View File

@ -0,0 +1,103 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/backend/s390/unwinding-info-writer-s390.h"
#include "src/compiler/backend/instruction.h"
namespace v8 {
namespace internal {
namespace compiler {
void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset,
const InstructionBlock* block) {
if (!enabled()) return;
block_will_exit_ = false;
DCHECK_LT(block->rpo_number().ToInt(),
static_cast<int>(block_initial_states_.size()));
const BlockInitialState* initial_state =
block_initial_states_[block->rpo_number().ToInt()];
if (!initial_state) return;
if (initial_state->saved_lr_ != saved_lr_) {
eh_frame_writer_.AdvanceLocation(pc_offset);
if (initial_state->saved_lr_) {
eh_frame_writer_.RecordRegisterSavedToStack(r14, kSystemPointerSize);
eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
} else {
eh_frame_writer_.RecordRegisterFollowsInitialRule(r14);
}
saved_lr_ = initial_state->saved_lr_;
}
}
void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
if (!enabled() || block_will_exit_) return;
for (const RpoNumber& successor : block->successors()) {
int successor_index = successor.ToInt();
DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
const BlockInitialState* existing_state =
block_initial_states_[successor_index];
// If we already had an entry for this BB, check that the values are the
// same we are trying to insert.
if (existing_state) {
DCHECK_EQ(existing_state->saved_lr_, saved_lr_);
} else {
block_initial_states_[successor_index] =
new (zone_) BlockInitialState(saved_lr_);
}
}
}
void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) {
if (!enabled()) return;
// Regardless of the type of frame constructed, the relevant part of the
// layout is always the one in the diagram:
//
// | .... | higher addresses
// +----------+ ^
// | LR | | |
// +----------+ | |
// | saved FP | | |
// +----------+ <-- FP v
// | .... | stack growth
//
// The LR is pushed on the stack, and we can record this fact at the end of
// the construction, since the LR itself is not modified in the process.
eh_frame_writer_.AdvanceLocation(at_pc);
eh_frame_writer_.RecordRegisterSavedToStack(r14, kSystemPointerSize);
eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
saved_lr_ = true;
}
void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) {
if (!enabled()) return;
// The lr is restored by the last operation in LeaveFrame().
eh_frame_writer_.AdvanceLocation(at_pc);
eh_frame_writer_.RecordRegisterFollowsInitialRule(r14);
saved_lr_ = false;
}
void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) {
if (!enabled()) return;
eh_frame_writer_.AdvanceLocation(pc_offset);
eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0);
eh_frame_writer_.RecordRegisterSavedToStack(r14, 0);
}
void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) {
if (!enabled()) return;
eh_frame_writer_.AdvanceLocation(pc_offset);
eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0);
eh_frame_writer_.RecordRegisterFollowsInitialRule(r14);
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,73 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_BACKEND_S390_UNWINDING_INFO_WRITER_S390_H_
#define V8_COMPILER_BACKEND_S390_UNWINDING_INFO_WRITER_S390_H_
#include "src/diagnostics/eh-frame.h"
#include "src/flags/flags.h"
namespace v8 {
namespace internal {
namespace compiler {
class InstructionBlock;
class UnwindingInfoWriter {
public:
explicit UnwindingInfoWriter(Zone* zone)
: zone_(zone),
eh_frame_writer_(zone),
saved_lr_(false),
block_will_exit_(false),
block_initial_states_(zone) {
if (enabled()) eh_frame_writer_.Initialize();
}
void SetNumberOfInstructionBlocks(int number) {
if (enabled()) block_initial_states_.resize(number);
}
void BeginInstructionBlock(int pc_offset, const InstructionBlock* block);
void EndInstructionBlock(const InstructionBlock* block);
void MarkLinkRegisterOnTopOfStack(int pc_offset);
void MarkPopLinkRegisterFromTopOfStack(int pc_offset);
void MarkFrameConstructed(int at_pc);
void MarkFrameDeconstructed(int at_pc);
void MarkBlockWillExit() { block_will_exit_ = true; }
void Finish(int code_size) {
if (enabled()) eh_frame_writer_.Finish(code_size);
}
EhFrameWriter* eh_frame_writer() {
return enabled() ? &eh_frame_writer_ : nullptr;
}
private:
bool enabled() const { return FLAG_perf_prof_unwinding_info; }
class BlockInitialState : public ZoneObject {
public:
explicit BlockInitialState(bool saved_lr) : saved_lr_(saved_lr) {}
bool saved_lr_;
};
Zone* zone_;
EhFrameWriter eh_frame_writer_;
bool saved_lr_;
bool block_will_exit_;
ZoneVector<const BlockInitialState*> block_initial_states_;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_BACKEND_S390_UNWINDING_INFO_WRITER_S390_H_

View File

@ -13,6 +13,10 @@
#include "src/compiler/backend/arm64/unwinding-info-writer-arm64.h"
#elif V8_TARGET_ARCH_X64
#include "src/compiler/backend/x64/unwinding-info-writer-x64.h"
#elif V8_TARGET_ARCH_S390X
#include "src/compiler/backend/s390/unwinding-info-writer-s390.h"
#elif V8_TARGET_ARCH_PPC64
#include "src/compiler/backend/ppc/unwinding-info-writer-ppc.h"
#else
// Placeholder for unsupported architectures.

View File

@ -9,8 +9,9 @@
#include "src/codegen/code-desc.h"
#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM) && \
!defined(V8_TARGET_ARCH_ARM64)
#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM) && \
!defined(V8_TARGET_ARCH_ARM64) && !defined(V8_TARGET_ARCH_S390X) && \
!defined(V8_TARGET_ARCH_PPC64)
// Placeholders for unsupported architectures.
@ -303,36 +304,44 @@ void EhFrameWriter::SetBaseAddressRegisterAndOffset(Register base_register,
base_register_ = base_register;
}
void EhFrameWriter::RecordRegisterSavedToStack(int register_code, int offset) {
void EhFrameWriter::RecordRegisterSavedToStack(int dwarf_register_code,
int offset) {
DCHECK_EQ(writer_state_, InternalState::kInitialized);
DCHECK_EQ(offset % EhFrameConstants::kDataAlignmentFactor, 0);
int factored_offset = offset / EhFrameConstants::kDataAlignmentFactor;
if (factored_offset >= 0) {
DCHECK_LE(register_code, EhFrameConstants::kSavedRegisterMask);
DCHECK_LE(dwarf_register_code, EhFrameConstants::kSavedRegisterMask);
WriteByte((EhFrameConstants::kSavedRegisterTag
<< EhFrameConstants::kSavedRegisterMaskSize) |
(register_code & EhFrameConstants::kSavedRegisterMask));
(dwarf_register_code & EhFrameConstants::kSavedRegisterMask));
WriteULeb128(factored_offset);
} else {
WriteOpcode(EhFrameConstants::DwarfOpcodes::kOffsetExtendedSf);
WriteULeb128(register_code);
WriteULeb128(dwarf_register_code);
WriteSLeb128(factored_offset);
}
}
void EhFrameWriter::RecordRegisterNotModified(Register name) {
RecordRegisterNotModified(RegisterToDwarfCode(name));
}
void EhFrameWriter::RecordRegisterNotModified(int dwarf_register_code) {
DCHECK_EQ(writer_state_, InternalState::kInitialized);
WriteOpcode(EhFrameConstants::DwarfOpcodes::kSameValue);
WriteULeb128(RegisterToDwarfCode(name));
WriteULeb128(dwarf_register_code);
}
void EhFrameWriter::RecordRegisterFollowsInitialRule(Register name) {
RecordRegisterFollowsInitialRule(RegisterToDwarfCode(name));
}
void EhFrameWriter::RecordRegisterFollowsInitialRule(int dwarf_register_code) {
DCHECK_EQ(writer_state_, InternalState::kInitialized);
int code = RegisterToDwarfCode(name);
DCHECK_LE(code, EhFrameConstants::kFollowInitialRuleMask);
DCHECK_LE(dwarf_register_code, EhFrameConstants::kFollowInitialRuleMask);
WriteByte((EhFrameConstants::kFollowInitialRuleTag
<< EhFrameConstants::kFollowInitialRuleMaskSize) |
(code & EhFrameConstants::kFollowInitialRuleMask));
(dwarf_register_code & EhFrameConstants::kFollowInitialRuleMask));
}
void EhFrameWriter::Finish(int code_size) {

View File

@ -102,11 +102,17 @@ class V8_EXPORT_PRIVATE EhFrameWriter {
RecordRegisterSavedToStack(RegisterToDwarfCode(name), offset);
}
// Directly accepts a DWARF register code, needed for
// handling pseudo-registers on some platforms.
void RecordRegisterSavedToStack(int dwarf_register_code, int offset);
// The register has not been modified from the previous frame.
void RecordRegisterNotModified(Register name);
void RecordRegisterNotModified(int dwarf_register_code);
// The register follows the rule defined in the CIE.
void RecordRegisterFollowsInitialRule(Register name);
void RecordRegisterFollowsInitialRule(int dwarf_register_code);
void Finish(int code_size);
@ -169,10 +175,6 @@ class V8_EXPORT_PRIVATE EhFrameWriter {
// Write nops until the size reaches a multiple of 8 bytes.
void WritePaddingToAlignedSize(int unpadded_size);
// Internal version that directly accepts a DWARF register code, needed for
// handling pseudo-registers on some platforms.
void RecordRegisterSavedToStack(int register_code, int offset);
int GetProcedureAddressOffset() const {
return fde_offset() + EhFrameConstants::kProcedureAddressOffsetInFde;
}

View File

@ -79,6 +79,8 @@ class PerfJitLogger : public CodeEventLogger {
static const uint32_t kElfMachARM = 40;
static const uint32_t kElfMachMIPS = 10;
static const uint32_t kElfMachARM64 = 183;
static const uint32_t kElfMachS390x = 22;
static const uint32_t kElfMachPPC64 = 21;
uint32_t GetElfMach() {
#if V8_TARGET_ARCH_IA32
@ -91,6 +93,10 @@ class PerfJitLogger : public CodeEventLogger {
return kElfMachMIPS;
#elif V8_TARGET_ARCH_ARM64
return kElfMachARM64;
#elif V8_TARGET_ARCH_S390X
return kElfMachS390x;
#elif V8_TARGET_ARCH_PPC64
return kElfMachPPC64;
#else
UNIMPLEMENTED();
return 0;

View File

@ -0,0 +1,57 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/ppc/constants-ppc.h"
#include "src/diagnostics/eh-frame.h"
namespace v8 {
namespace internal {
const int EhFrameConstants::kCodeAlignmentFactor = 4;
// all PPC are 4 bytes instruction
const int EhFrameConstants::kDataAlignmentFactor = -8; // 64-bit always -8
void EhFrameWriter::WriteReturnAddressRegisterCode() {
WriteULeb128(kLrDwarfCode);
}
void EhFrameWriter::WriteInitialStateInCie() {
SetBaseAddressRegisterAndOffset(fp, 0);
RecordRegisterNotModified(kLrDwarfCode);
}
// static
int EhFrameWriter::RegisterToDwarfCode(Register name) {
switch (name.code()) {
case kRegCode_fp:
return kFpDwarfCode;
case kRegCode_sp:
return kSpDwarfCode;
case kRegCode_r0:
return kR0DwarfCode;
default:
UNIMPLEMENTED();
return -1;
}
}
#ifdef ENABLE_DISASSEMBLER
// static
const char* EhFrameDisassembler::DwarfRegisterCodeToString(int code) {
switch (code) {
case kFpDwarfCode:
return "fp";
case kSpDwarfCode:
return "sp";
default:
UNIMPLEMENTED();
return nullptr;
}
}
#endif
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,65 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/s390/assembler-s390-inl.h"
#include "src/diagnostics/eh-frame.h"
namespace v8 {
namespace internal {
static const int kR0DwarfCode = 0;
static const int kFpDwarfCode = 11; // frame-pointer
static const int kR14DwarfCode = 14; // return-address(lr)
static const int kSpDwarfCode = 15; // stack-pointer
const int EhFrameConstants::kCodeAlignmentFactor = 2; // 1 or 2 in s390
const int EhFrameConstants::kDataAlignmentFactor = -8;
void EhFrameWriter::WriteReturnAddressRegisterCode() {
WriteULeb128(kR14DwarfCode);
}
void EhFrameWriter::WriteInitialStateInCie() {
SetBaseAddressRegisterAndOffset(fp, 0);
RecordRegisterNotModified(r14);
}
// static
int EhFrameWriter::RegisterToDwarfCode(Register name) {
switch (name.code()) {
case kRegCode_fp:
return kFpDwarfCode;
case kRegCode_r14:
return kR14DwarfCode;
case kRegCode_sp:
return kSpDwarfCode;
case kRegCode_r0:
return kR0DwarfCode;
default:
UNIMPLEMENTED();
return -1;
}
}
#ifdef ENABLE_DISASSEMBLER
// static
const char* EhFrameDisassembler::DwarfRegisterCodeToString(int code) {
switch (code) {
case kFpDwarfCode:
return "fp";
case kR14DwarfCode:
return "lr";
case kSpDwarfCode:
return "sp";
default:
UNIMPLEMENTED();
return nullptr;
}
}
#endif
} // namespace internal
} // namespace v8