Skip to content

Commit 9e9ba2e

Browse files
committedNov 9, 2021
8275646: Implement optimized upcall stubs on AArch64
Reviewed-by: jvernee
1 parent 330a9f8 commit 9e9ba2e

9 files changed

+366
-34
lines changed
 

‎src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp

+22-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2019, Arm Limited. All rights reserved.
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2019, 2021, Arm Limited. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -94,8 +94,26 @@ const BufferLayout ForeignGlobals::parse_buffer_layout_impl(jobject jlayout) con
9494
}
9595

9696
const CallRegs ForeignGlobals::parse_call_regs_impl(jobject jconv) const {
97-
ShouldNotCallThis();
98-
return {};
97+
oop conv_oop = JNIHandles::resolve_non_null(jconv);
98+
objArrayOop arg_regs_oop = oop_cast<objArrayOop>(conv_oop->obj_field(CallConvOffsets.arg_regs_offset));
99+
objArrayOop ret_regs_oop = oop_cast<objArrayOop>(conv_oop->obj_field(CallConvOffsets.ret_regs_offset));
100+
101+
CallRegs result;
102+
result._args_length = arg_regs_oop->length();
103+
result._arg_regs = NEW_RESOURCE_ARRAY(VMReg, result._args_length);
104+
105+
result._rets_length = ret_regs_oop->length();
106+
result._ret_regs = NEW_RESOURCE_ARRAY(VMReg, result._rets_length);
107+
108+
for (int i = 0; i < result._args_length; i++) {
109+
result._arg_regs[i] = parse_vmstorage(arg_regs_oop->obj_at(i));
110+
}
111+
112+
for (int i = 0; i < result._rets_length; i++) {
113+
result._ret_regs[i] = parse_vmstorage(ret_regs_oop->obj_at(i));
114+
}
115+
116+
return result;
99117
}
100118

101119
enum class RegType {

‎src/hotspot/cpu/aarch64/frame_aarch64.cpp

+33-6
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
115115
if (is_entry_frame()) {
116116
// an entry frame must have a valid fp.
117117
return fp_safe && is_entry_frame_valid(thread);
118+
} else if (is_optimized_entry_frame()) {
119+
return fp_safe;
118120
}
119121

120122
intptr_t* sender_sp = NULL;
@@ -211,6 +213,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
211213
address jcw = (address)sender.entry_frame_call_wrapper();
212214

213215
return thread->is_in_stack_range_excl(jcw, (address)sender.fp());
216+
} else if (sender_blob->is_optimized_entry_blob()) {
217+
return false;
214218
}
215219

216220
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
@@ -363,18 +367,39 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
363367
}
364368

365369
OptimizedEntryBlob::FrameData* OptimizedEntryBlob::frame_data_for_frame(const frame& frame) const {
366-
ShouldNotCallThis();
367-
return nullptr;
370+
assert(frame.is_optimized_entry_frame(), "wrong frame");
371+
// need unextended_sp here, since normal sp is wrong for interpreter callees
372+
return reinterpret_cast<OptimizedEntryBlob::FrameData*>(
373+
reinterpret_cast<char*>(frame.unextended_sp()) + in_bytes(_frame_data_offset));
368374
}
369375

370376
bool frame::optimized_entry_frame_is_first() const {
371-
ShouldNotCallThis();
372-
return false;
377+
assert(is_optimized_entry_frame(), "must be optimzed entry frame");
378+
OptimizedEntryBlob* blob = _cb->as_optimized_entry_blob();
379+
JavaFrameAnchor* jfa = blob->jfa_for_frame(*this);
380+
return jfa->last_Java_sp() == NULL;
373381
}
374382

375383
frame frame::sender_for_optimized_entry_frame(RegisterMap* map) const {
376-
ShouldNotCallThis();
377-
return {};
384+
assert(map != NULL, "map must be set");
385+
OptimizedEntryBlob* blob = _cb->as_optimized_entry_blob();
386+
// Java frame called from C; skip all C frames and return top C
387+
// frame of that chunk as the sender
388+
JavaFrameAnchor* jfa = blob->jfa_for_frame(*this);
389+
assert(!optimized_entry_frame_is_first(), "must have a frame anchor to go back to");
390+
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
391+
// Since we are walking the stack now this nested anchor is obviously walkable
392+
// even if it wasn't when it was stacked.
393+
if (!jfa->walkable()) {
394+
// Capture _last_Java_pc (if needed) and mark anchor walkable.
395+
jfa->capture_last_Java_pc();
396+
}
397+
map->clear();
398+
assert(map->include_argument_oops(), "should be set by clear");
399+
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
400+
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
401+
402+
return fr;
378403
}
379404

380405
//------------------------------------------------------------------------------
@@ -507,6 +532,8 @@ frame frame::sender_raw(RegisterMap* map) const {
507532

508533
if (is_entry_frame())
509534
return sender_for_entry_frame(map);
535+
if (is_optimized_entry_frame())
536+
return sender_for_optimized_entry_frame(map);
510537
if (is_interpreted_frame())
511538
return sender_for_interpreter_frame(map);
512539
assert(_cb == CodeCache::find_blob(pc()),"Must be the same");

‎src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2075,7 +2075,7 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
20752075
cbz(value, done); // Use NULL as-is.
20762076

20772077
STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
2078-
tbz(r0, 0, not_weak); // Test for jweak tag.
2078+
tbz(value, 0, not_weak); // Test for jweak tag.
20792079

20802080
// Resolve jweak.
20812081
access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, value,

0 commit comments

Comments
 (0)
Please sign in to comment.