Skip to content

Commit 8310948

Browse files
authored
Merge 22642ff into 19c9388
2 parents 19c9388 + 22642ff commit 8310948

File tree

49 files changed

+1164
-362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1164
-362
lines changed

src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,6 +2862,7 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest,
28622862
if (info != nullptr) {
28632863
add_call_info_here(info);
28642864
}
2865+
assert(__ last_calls_return_pc() == __ pc(), "pcn not at return pc");
28652866
__ post_call_nop();
28662867
}
28672868

src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ inline void Thaw<ConfigT>::patch_caller_links(intptr_t* sp, intptr_t* bottom) {
350350
if (is_entry_frame) {
351351
callers_sp = _cont.entryFP();
352352
} else {
353-
CodeBlob* cb = CodeCache::find_blob(pc);
353+
CodeBlob* cb = CodeCache::find_blob_fast(pc);
354354
callers_sp = sp + cb->frame_size();
355355
}
356356
// set the back link

src/hotspot/cpu/ppc/frame_ppc.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
136136

137137
// It should be safe to construct the sender though it might not be valid.
138138

139-
frame sender(sender_sp, sender_pc);
139+
frame sender(sender_sp, sender_pc, nullptr /* unextended_sp */, nullptr /* fp */, sender_blob);
140140

141141
// Do we have a valid fp?
142142
address sender_fp = (address) sender.fp();
@@ -196,12 +196,12 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const {
196196
assert(map->include_argument_oops(), "should be set by clear");
197197

198198
if (jfa->last_Java_pc() != nullptr) {
199-
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc());
199+
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc(), kind::code_blob);
200200
return fr;
201201
}
202202
// Last_java_pc is not set, if we come here from compiled code. The
203203
// constructor retrieves the PC from the stack.
204-
frame fr(jfa->last_Java_sp());
204+
frame fr(jfa->last_Java_sp(), nullptr, kind::code_blob);
205205
return fr;
206206
}
207207

@@ -229,7 +229,7 @@ frame frame::sender_for_upcall_stub_frame(RegisterMap* map) const {
229229
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
230230
map->clear();
231231
assert(map->include_argument_oops(), "should be set by clear");
232-
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc());
232+
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc(), kind::code_blob);
233233

234234
return fr;
235235
}
@@ -451,7 +451,7 @@ intptr_t *frame::initial_deoptimization_info() {
451451
#ifndef PRODUCT
452452
// This is a generic constructor which is only used by pns() in debug.cpp.
453453
// fp is dropped and gets determined by backlink.
454-
frame::frame(void* sp, void* fp, void* pc) : frame((intptr_t*)sp, (address)pc) {}
454+
frame::frame(void* sp, void* fp, void* pc) : frame((intptr_t*)sp, (address)pc, kind::unknown) {}
455455
#endif
456456

457457
BasicObjectLock* frame::interpreter_frame_monitor_end() const {

src/hotspot/cpu/ppc/frame_ppc.hpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,16 +393,26 @@
393393
inline common_abi* own_abi() const { return (common_abi*) _sp; }
394394
inline common_abi* callers_abi() const { return (common_abi*) _fp; }
395395

396+
enum class kind {
397+
unknown, // The frame's pc is not necessarily in the CodeCache.
398+
// CodeCache::find_blob_fast(void* pc) can yield wrong results in this case and must not be used.
399+
code_blob, // The frame's pc is known to be in the CodeCache but it is likely not in an nmethod.
400+
// CodeCache::find_blob_fast() will be correct but not faster in this case.
401+
nmethod // This is likely the frame of a nmethod.
402+
// The code cache lookup is optimized based on NativePostCallNops.
403+
};
404+
396405
private:
397406

398407
// Initialize frame members (_pc and _sp must be given)
399-
inline void setup();
408+
inline void setup(kind knd);
400409

401410
public:
402411

403412
// Constructors
404413
inline frame(intptr_t* sp, intptr_t* fp, address pc);
405-
inline frame(intptr_t* sp, address pc, intptr_t* unextended_sp = nullptr, intptr_t* fp = nullptr, CodeBlob* cb = nullptr);
414+
inline frame(intptr_t* sp, address pc, kind knd = kind::nmethod);
415+
inline frame(intptr_t* sp, address pc, intptr_t* unextended_sp, intptr_t* fp = nullptr, CodeBlob* cb = nullptr);
406416
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map);
407417
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map, bool on_heap);
408418

src/hotspot/cpu/ppc/frame_ppc.inline.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
// Inline functions for ppc64 frames:
3636

3737
// Initialize frame members (_sp must be given)
38-
inline void frame::setup() {
38+
inline void frame::setup(kind knd) {
3939
if (_pc == nullptr) {
4040
_pc = (address)own_abi()->lr;
4141
assert(_pc != nullptr, "must have PC");
4242
}
4343

4444
if (_cb == nullptr) {
45-
_cb = CodeCache::find_blob(_pc);
45+
_cb = (knd == kind::nmethod) ? CodeCache::find_blob_fast(_pc) : CodeCache::find_blob(_pc);
4646
}
4747

4848
if (_unextended_sp == nullptr) {
@@ -89,21 +89,27 @@ inline void frame::setup() {
8989
inline frame::frame() : _sp(nullptr), _pc(nullptr), _cb(nullptr), _oop_map(nullptr), _deopt_state(unknown),
9090
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(nullptr), _fp(nullptr) {}
9191

92-
inline frame::frame(intptr_t* sp) : frame(sp, nullptr) {}
92+
inline frame::frame(intptr_t* sp) : frame(sp, nullptr, kind::nmethod) {}
9393

9494
inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) : frame(sp, pc, nullptr, fp, nullptr) {}
9595

96+
inline frame::frame(intptr_t* sp, address pc, kind knd)
97+
: _sp(sp), _pc(pc), _cb(nullptr), _oop_map(nullptr),
98+
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(sp), _fp(nullptr) {
99+
setup(knd);
100+
}
101+
96102
inline frame::frame(intptr_t* sp, address pc, intptr_t* unextended_sp, intptr_t* fp, CodeBlob* cb)
97103
: _sp(sp), _pc(pc), _cb(cb), _oop_map(nullptr),
98104
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(unextended_sp), _fp(fp) {
99-
setup();
105+
setup(kind::nmethod);
100106
}
101107

102108
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map)
103109
: _sp(sp), _pc(pc), _cb(cb), _oop_map(oop_map),
104110
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(unextended_sp), _fp(fp) {
105111
assert(_cb != nullptr, "pc: " INTPTR_FORMAT, p2i(pc));
106-
setup();
112+
setup(kind::nmethod);
107113
}
108114

109115
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb,
@@ -113,7 +119,7 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address
113119
// In thaw, non-heap frames use this constructor to pass oop_map. I don't know why.
114120
assert(_on_heap || _cb != nullptr, "these frames are always heap frames");
115121
if (cb != nullptr) {
116-
setup();
122+
setup(kind::nmethod);
117123
}
118124
#ifdef ASSERT
119125
// The following assertion has been disabled because it would sometime trap for Continuation.run,
@@ -300,7 +306,7 @@ inline frame frame::sender_raw(RegisterMap* map) const {
300306

301307
// Must be native-compiled frame, i.e. the marshaling code for native
302308
// methods that exists in the core system.
303-
return frame(sender_sp(), sender_pc());
309+
return frame(sender_sp(), sender_pc(), kind::code_blob);
304310
}
305311

306312
inline frame frame::sender(RegisterMap* map) const {

src/hotspot/cpu/ppc/macroAssembler_ppc.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1187,8 +1187,12 @@ void MacroAssembler::post_call_nop() {
11871187
if (!Continuations::enabled()) {
11881188
return;
11891189
}
1190+
// We use CMPI/CMPLI instructions to encode post call nops.
1191+
// Refer to NativePostCallNop for details.
1192+
relocate(post_call_nop_Relocation::spec());
11901193
InlineSkippedInstructionsCounter skipCounter(this);
1191-
nop();
1194+
Assembler::emit_int32(Assembler::CMPLI_OPCODE | Assembler::opp_u_field(1, 9, 9));
1195+
assert(is_post_call_nop(*(int*)(pc() - 4)), "post call not not found");
11921196
}
11931197

11941198
void MacroAssembler::call_VM_base(Register oop_result,

src/hotspot/cpu/ppc/macroAssembler_ppc.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ class MacroAssembler: public Assembler {
417417
inline void call_stub_and_return_to(Register function_entry, Register return_pc);
418418

419419
void post_call_nop();
420+
static bool is_post_call_nop(int instr_bits) {
421+
const uint32_t nineth_bit = opp_u_field(1, 9, 9);
422+
const uint32_t opcode_mask = 0b111110 << OPCODE_SHIFT;
423+
const uint32_t pcn_mask = opcode_mask | nineth_bit;
424+
return (instr_bits & pcn_mask) == (Assembler::CMPLI_OPCODE | nineth_bit);
425+
}
420426

421427
//
422428
// Java utilities

src/hotspot/cpu/ppc/nativeInst_ppc.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,31 @@ void NativePostCallNop::make_deopt() {
429429
NativeDeoptInstruction::insert(addr_at(0));
430430
}
431431

432+
bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
433+
int32_t i2, i1;
434+
assert(is_aligned(cb_offset, 4), "cb offset alignment does not match instruction alignment");
435+
assert(!decode(i1, i2), "already patched");
436+
437+
cb_offset = cb_offset >> 2;
438+
if (((oopmap_slot & ppc_oopmap_slot_mask) != oopmap_slot) || ((cb_offset & ppc_cb_offset_mask) != cb_offset)) {
439+
return false; // cannot encode
440+
}
441+
const uint32_t data = oopmap_slot << ppc_cb_offset_bits | cb_offset;
442+
const uint32_t lo_data = data & ppc_data_lo_mask;
443+
const uint32_t hi_data = data >> ppc_data_lo_bits;
444+
const uint32_t nineth_bit = 1 << (31 - 9);
445+
uint32_t instr = Assembler::CMPLI_OPCODE | hi_data << ppc_data_hi_shift | nineth_bit | lo_data;
446+
*(uint32_t*)addr_at(0) = instr;
447+
448+
int32_t oopmap_slot_dec, cb_offset_dec;
449+
assert(is_post_call_nop(), "pcn not recognized");
450+
assert(decode(oopmap_slot_dec, cb_offset_dec), "encoding failed");
451+
assert(oopmap_slot == oopmap_slot_dec, "oopmap slot encoding is wrong");
452+
assert((cb_offset << 2) == cb_offset_dec, "cb offset encoding is wrong");
453+
454+
return true; // encoding succeeded
455+
}
456+
432457
void NativeDeoptInstruction::verify() {
433458
}
434459

src/hotspot/cpu/ppc/nativeInst_ppc.hpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class NativeInstruction {
5151
friend class Relocation;
5252

5353
public:
54-
bool is_nop() const { return Assembler::is_nop(long_at(0)); }
54+
bool is_post_call_nop() const { return MacroAssembler::is_post_call_nop(long_at(0)); }
5555

5656
bool is_jump() const { return Assembler::is_b(long_at(0)); } // See NativeGeneralJump.
5757

@@ -506,10 +506,50 @@ class NativeMovRegMem: public NativeInstruction {
506506
};
507507

508508
class NativePostCallNop: public NativeInstruction {
509+
510+
// We use CMPI/CMPLI to represent Post Call Nops (PCN)
511+
512+
// Bit |0 5|6 |9 |10|11 |16 31|
513+
// +--------------------------------------------------------------+
514+
// Field |OPCODE |BF |/ |L |RA |SI |
515+
// +--------------------------------------------------------------+
516+
// |0 0 1 0 1|DATA HI| 1| DATA LO |
517+
// | |4 bits | | 22 bits |
518+
//
519+
// Bit 9 is always 1 for PCNs to distinguish them from regular CMPI/CMPLI
520+
//
521+
// Using both, CMPLI (opcode 10 = 0b001010) and CMPI (opcode 11 = 0b001011) for
522+
// PCNs allows using bit 5 from the opcode to encode DATA HI.
523+
524+
enum {
525+
ppc_data_lo_bits = 31 - 9,
526+
ppc_data_lo_mask = right_n_bits(ppc_data_lo_bits),
527+
ppc_data_hi_bits = 9 - 5,
528+
ppc_data_hi_shift = ppc_data_lo_bits + 1,
529+
ppc_data_hi_mask = right_n_bits(ppc_data_hi_bits) << ppc_data_hi_shift,
530+
ppc_data_bits = ppc_data_lo_bits + ppc_data_hi_bits,
531+
532+
ppc_oopmap_slot_bits = 9,
533+
ppc_oopmap_slot_mask = right_n_bits(ppc_oopmap_slot_bits),
534+
ppc_cb_offset_bits = ppc_data_bits - ppc_oopmap_slot_bits,
535+
ppc_cb_offset_mask = right_n_bits(ppc_cb_offset_bits),
536+
};
537+
509538
public:
510-
bool check() const { return is_nop(); }
511-
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const { return false; }
512-
bool patch(int32_t oopmap_slot, int32_t cb_offset) { return false; }
539+
bool check() const { return is_post_call_nop(); }
540+
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const {
541+
uint32_t instr_bits = long_at(0);
542+
uint32_t data_lo = instr_bits & ppc_data_lo_mask;
543+
uint32_t data_hi = (instr_bits & ppc_data_hi_mask) >> 1;
544+
uint32_t data = data_hi | data_lo;
545+
if (data == 0) {
546+
return false; // no data found
547+
}
548+
cb_offset = (data & ppc_cb_offset_mask) << 2;
549+
oopmap_slot = data >> ppc_cb_offset_bits;
550+
return true; // decoding succeeded
551+
}
552+
bool patch(int32_t oopmap_slot, int32_t cb_offset);
513553
void make_deopt();
514554
};
515555

src/hotspot/os_cpu/aix_ppc/javaThread_aix_ppc.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ frame JavaThread::pd_last_frame() {
3737
intptr_t* sp = last_Java_sp();
3838
address pc = _anchor.last_Java_pc();
3939

40-
return frame(sp, pc);
40+
// Likely the frame of a RuntimeStub.
41+
return frame(sp, pc, frame::kind::code_blob);
4142
}
4243

4344
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
@@ -50,7 +51,7 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
5051
// pc can be seen as null because not all writers use store pc + release store sp.
5152
// Simply discard the sample in this very rare case.
5253
if (pc == nullptr) return false;
53-
*fr_addr = frame(sp, pc);
54+
*fr_addr = frame(sp, pc, frame::kind::code_blob);
5455
return true;
5556
}
5657

@@ -66,7 +67,8 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
6667
return false;
6768
}
6869

69-
frame ret_frame((intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/], pc);
70+
// pc could refer to a native address outside the code cache even though the thread isInJava.
71+
frame ret_frame((intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/], pc, frame::kind::unknown);
7072

7173
if (ret_frame.fp() == nullptr) {
7274
// The found frame does not have a valid frame pointer.

0 commit comments

Comments
 (0)