Skip to content

Commit b6ef251

Browse files
Junliang YanCommit Bot
authored andcommitted
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}
1 parent 3ee5dbc commit b6ef251

14 files changed

Lines changed: 559 additions & 30 deletions

BUILD.gn

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,9 +3160,12 @@ v8_source_set("v8_base_without_compiler") {
31603160
"src/compiler/backend/ppc/instruction-codes-ppc.h",
31613161
"src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
31623162
"src/compiler/backend/ppc/instruction-selector-ppc.cc",
3163+
"src/compiler/backend/ppc/unwinding-info-writer-ppc.cc",
3164+
"src/compiler/backend/ppc/unwinding-info-writer-ppc.h",
31633165
"src/debug/ppc/debug-ppc.cc",
31643166
"src/deoptimizer/ppc/deoptimizer-ppc.cc",
31653167
"src/diagnostics/ppc/disasm-ppc.cc",
3168+
"src/diagnostics/ppc/eh-frame-ppc.cc",
31663169
"src/execution/ppc/frame-constants-ppc.cc",
31673170
"src/execution/ppc/frame-constants-ppc.h",
31683171
"src/execution/ppc/simulator-ppc.cc",
@@ -3187,9 +3190,12 @@ v8_source_set("v8_base_without_compiler") {
31873190
"src/compiler/backend/s390/instruction-codes-s390.h",
31883191
"src/compiler/backend/s390/instruction-scheduler-s390.cc",
31893192
"src/compiler/backend/s390/instruction-selector-s390.cc",
3193+
"src/compiler/backend/s390/unwinding-info-writer-s390.cc",
3194+
"src/compiler/backend/s390/unwinding-info-writer-s390.h",
31903195
"src/debug/s390/debug-s390.cc",
31913196
"src/deoptimizer/s390/deoptimizer-s390.cc",
31923197
"src/diagnostics/s390/disasm-s390.cc",
3198+
"src/diagnostics/s390/eh-frame-s390.cc",
31933199
"src/execution/s390/frame-constants-s390.cc",
31943200
"src/execution/s390/frame-constants-s390.h",
31953201
"src/execution/s390/simulator-s390.cc",

src/codegen/ppc/constants-ppc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,4 +2992,9 @@ class DoubleRegisters {
29922992
} // namespace internal
29932993
} // namespace v8
29942994

2995+
static constexpr int kR0DwarfCode = 0;
2996+
static constexpr int kFpDwarfCode = 31; // frame-pointer
2997+
static constexpr int kLrDwarfCode = 65; // return-address(lr)
2998+
static constexpr int kSpDwarfCode = 1; // stack-pointer (sp)
2999+
29953000
#endif // V8_CODEGEN_PPC_CONSTANTS_PPC_H_

src/compiler/backend/ppc/code-generator-ppc.cc

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
129129
public:
130130
OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
131131
Register value, Register scratch0, Register scratch1,
132-
RecordWriteMode mode, StubCallMode stub_mode)
132+
RecordWriteMode mode, StubCallMode stub_mode,
133+
UnwindingInfoWriter* unwinding_info_writer)
133134
: OutOfLineCode(gen),
134135
object_(object),
135136
offset_(offset),
@@ -140,11 +141,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
140141
mode_(mode),
141142
stub_mode_(stub_mode),
142143
must_save_lr_(!gen->frame_access_state()->has_frame()),
144+
unwinding_info_writer_(unwinding_info_writer),
143145
zone_(gen->zone()) {}
144146

145147
OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset,
146148
Register value, Register scratch0, Register scratch1,
147-
RecordWriteMode mode, StubCallMode stub_mode)
149+
RecordWriteMode mode, StubCallMode stub_mode,
150+
UnwindingInfoWriter* unwinding_info_writer)
148151
: OutOfLineCode(gen),
149152
object_(object),
150153
offset_(no_reg),
@@ -155,6 +158,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
155158
mode_(mode),
156159
stub_mode_(stub_mode),
157160
must_save_lr_(!gen->frame_access_state()->has_frame()),
161+
unwinding_info_writer_(unwinding_info_writer),
158162
zone_(gen->zone()) {}
159163

160164
void Generate() final {
@@ -180,6 +184,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
180184
// We need to save and restore lr if the frame was elided.
181185
__ mflr(scratch0_);
182186
__ Push(scratch0_);
187+
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset());
183188
}
184189
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
185190
__ CallEphemeronKeyBarrier(object_, scratch1_, save_fp_mode);
@@ -194,6 +199,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
194199
// We need to save and restore lr if the frame was elided.
195200
__ Pop(scratch0_);
196201
__ mtlr(scratch0_);
202+
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
197203
}
198204
}
199205

@@ -207,6 +213,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
207213
RecordWriteMode const mode_;
208214
StubCallMode stub_mode_;
209215
bool must_save_lr_;
216+
UnwindingInfoWriter* const unwinding_info_writer_;
210217
Zone* zone_;
211218
};
212219

@@ -675,6 +682,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, Instruction* instr,
675682

676683
void CodeGenerator::AssembleDeconstructFrame() {
677684
__ LeaveFrame(StackFrame::MANUAL);
685+
unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset());
678686
}
679687

680688
void CodeGenerator::AssemblePrepareTailCall() {
@@ -1182,16 +1190,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
11821190
AddressingModeField::decode(instr->opcode());
11831191
if (addressing_mode == kMode_MRI) {
11841192
int32_t offset = i.InputInt32(1);
1185-
ool = new (zone())
1186-
OutOfLineRecordWrite(this, object, offset, value, scratch0,
1187-
scratch1, mode, DetermineStubCallMode());
1193+
ool = new (zone()) OutOfLineRecordWrite(
1194+
this, object, offset, value, scratch0, scratch1, mode,
1195+
DetermineStubCallMode(), &unwinding_info_writer_);
11881196
__ StoreP(value, MemOperand(object, offset));
11891197
} else {
11901198
DCHECK_EQ(kMode_MRR, addressing_mode);
11911199
Register offset(i.InputRegister(1));
1192-
ool = new (zone())
1193-
OutOfLineRecordWrite(this, object, offset, value, scratch0,
1194-
scratch1, mode, DetermineStubCallMode());
1200+
ool = new (zone()) OutOfLineRecordWrite(
1201+
this, object, offset, value, scratch0, scratch1, mode,
1202+
DetermineStubCallMode(), &unwinding_info_writer_);
11951203
__ StorePX(value, MemOperand(object, offset));
11961204
}
11971205
__ CheckPageFlag(object, scratch0,
@@ -2407,6 +2415,7 @@ void CodeGenerator::AssembleConstructFrame() {
24072415
}
24082416
}
24092417
}
2418+
unwinding_info_writer_.MarkFrameConstructed(__ pc_offset());
24102419
}
24112420

24122421
int required_slots =
@@ -2517,6 +2526,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
25172526
__ MultiPopDoubles(double_saves);
25182527
}
25192528
PPCOperandConverter g(this, nullptr);
2529+
unwinding_info_writer_.MarkBlockWillExit();
25202530

25212531
if (call_descriptor->IsCFunctionCall()) {
25222532
AssembleDeconstructFrame();
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2016 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "src/compiler/backend/ppc/unwinding-info-writer-ppc.h"
6+
#include "src/compiler/backend/instruction.h"
7+
8+
namespace v8 {
9+
namespace internal {
10+
namespace compiler {
11+
void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset,
12+
const InstructionBlock* block) {
13+
if (!enabled()) return;
14+
15+
block_will_exit_ = false;
16+
17+
DCHECK_LT(block->rpo_number().ToInt(),
18+
static_cast<int>(block_initial_states_.size()));
19+
const BlockInitialState* initial_state =
20+
block_initial_states_[block->rpo_number().ToInt()];
21+
if (!initial_state) return;
22+
if (initial_state->saved_lr_ != saved_lr_) {
23+
eh_frame_writer_.AdvanceLocation(pc_offset);
24+
if (initial_state->saved_lr_) {
25+
eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode,
26+
kSystemPointerSize);
27+
eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
28+
} else {
29+
eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
30+
}
31+
saved_lr_ = initial_state->saved_lr_;
32+
}
33+
}
34+
35+
void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
36+
if (!enabled() || block_will_exit_) return;
37+
38+
for (const RpoNumber& successor : block->successors()) {
39+
int successor_index = successor.ToInt();
40+
DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
41+
const BlockInitialState* existing_state =
42+
block_initial_states_[successor_index];
43+
44+
// If we already had an entry for this BB, check that the values are the
45+
// same we are trying to insert.
46+
if (existing_state) {
47+
DCHECK_EQ(existing_state->saved_lr_, saved_lr_);
48+
} else {
49+
block_initial_states_[successor_index] =
50+
new (zone_) BlockInitialState(saved_lr_);
51+
}
52+
}
53+
}
54+
55+
void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) {
56+
if (!enabled()) return;
57+
58+
// Regardless of the type of frame constructed, the relevant part of the
59+
// layout is always the one in the diagram:
60+
//
61+
// | .... | higher addresses
62+
// +----------+ ^
63+
// | LR | | |
64+
// +----------+ | |
65+
// | saved FP | | |
66+
// +----------+ <-- FP v
67+
// | .... | stack growth
68+
//
69+
// The LR is pushed on the stack, and we can record this fact at the end of
70+
// the construction, since the LR itself is not modified in the process.
71+
eh_frame_writer_.AdvanceLocation(at_pc);
72+
eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode,
73+
kSystemPointerSize);
74+
eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
75+
saved_lr_ = true;
76+
}
77+
78+
void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) {
79+
if (!enabled()) return;
80+
81+
// The lr is restored by the last operation in LeaveFrame().
82+
eh_frame_writer_.AdvanceLocation(at_pc);
83+
eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
84+
saved_lr_ = false;
85+
}
86+
87+
void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) {
88+
if (!enabled()) return;
89+
90+
eh_frame_writer_.AdvanceLocation(pc_offset);
91+
eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0);
92+
eh_frame_writer_.RecordRegisterSavedToStack(r30, 0);
93+
}
94+
95+
void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) {
96+
if (!enabled()) return;
97+
98+
eh_frame_writer_.AdvanceLocation(pc_offset);
99+
eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0);
100+
eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
101+
}
102+
103+
} // namespace compiler
104+
} // namespace internal
105+
} // namespace v8
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2016 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef V8_COMPILER_BACKEND_PPC_UNWINDING_INFO_WRITER_PPC_H_
6+
#define V8_COMPILER_BACKEND_PPC_UNWINDING_INFO_WRITER_PPC_H_
7+
8+
#include "src/diagnostics/eh-frame.h"
9+
#include "src/flags/flags.h"
10+
11+
namespace v8 {
12+
namespace internal {
13+
namespace compiler {
14+
15+
class InstructionBlock;
16+
17+
class UnwindingInfoWriter {
18+
public:
19+
explicit UnwindingInfoWriter(Zone* zone)
20+
: zone_(zone),
21+
eh_frame_writer_(zone),
22+
saved_lr_(false),
23+
block_will_exit_(false),
24+
block_initial_states_(zone) {
25+
if (enabled()) eh_frame_writer_.Initialize();
26+
}
27+
28+
void SetNumberOfInstructionBlocks(int number) {
29+
if (enabled()) block_initial_states_.resize(number);
30+
}
31+
32+
void BeginInstructionBlock(int pc_offset, const InstructionBlock* block);
33+
void EndInstructionBlock(const InstructionBlock* block);
34+
35+
void MarkLinkRegisterOnTopOfStack(int pc_offset);
36+
void MarkPopLinkRegisterFromTopOfStack(int pc_offset);
37+
38+
void MarkFrameConstructed(int at_pc);
39+
void MarkFrameDeconstructed(int at_pc);
40+
41+
void MarkBlockWillExit() { block_will_exit_ = true; }
42+
43+
void Finish(int code_size) {
44+
if (enabled()) eh_frame_writer_.Finish(code_size);
45+
}
46+
47+
EhFrameWriter* eh_frame_writer() {
48+
return enabled() ? &eh_frame_writer_ : nullptr;
49+
}
50+
51+
private:
52+
bool enabled() const { return FLAG_perf_prof_unwinding_info; }
53+
54+
class BlockInitialState : public ZoneObject {
55+
public:
56+
explicit BlockInitialState(bool saved_lr) : saved_lr_(saved_lr) {}
57+
58+
bool saved_lr_;
59+
};
60+
61+
Zone* zone_;
62+
EhFrameWriter eh_frame_writer_;
63+
bool saved_lr_;
64+
bool block_will_exit_;
65+
66+
ZoneVector<const BlockInitialState*> block_initial_states_;
67+
};
68+
69+
} // namespace compiler
70+
} // namespace internal
71+
} // namespace v8
72+
73+
#endif // V8_COMPILER_BACKEND_PPC_UNWINDING_INFO_WRITER_PPC_H_

0 commit comments

Comments
 (0)