Skip to content
Permalink
Browse files
8275646: Implement optimized upcall stubs on AArch64
Reviewed-by: jvernee
  • Loading branch information
nick-arm committed Nov 9, 2021
1 parent 330a9f8 commit 9e9ba2e99d3218f37b89e9cd0dae431f471be487
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Arm Limited. All rights reserved.
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
}

const CallRegs ForeignGlobals::parse_call_regs_impl(jobject jconv) const {
ShouldNotCallThis();
return {};
oop conv_oop = JNIHandles::resolve_non_null(jconv);
objArrayOop arg_regs_oop = oop_cast<objArrayOop>(conv_oop->obj_field(CallConvOffsets.arg_regs_offset));
objArrayOop ret_regs_oop = oop_cast<objArrayOop>(conv_oop->obj_field(CallConvOffsets.ret_regs_offset));

CallRegs result;
result._args_length = arg_regs_oop->length();
result._arg_regs = NEW_RESOURCE_ARRAY(VMReg, result._args_length);

result._rets_length = ret_regs_oop->length();
result._ret_regs = NEW_RESOURCE_ARRAY(VMReg, result._rets_length);

for (int i = 0; i < result._args_length; i++) {
result._arg_regs[i] = parse_vmstorage(arg_regs_oop->obj_at(i));
}

for (int i = 0; i < result._rets_length; i++) {
result._ret_regs[i] = parse_vmstorage(ret_regs_oop->obj_at(i));
}

return result;
}

enum class RegType {
@@ -115,6 +115,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
if (is_entry_frame()) {
// an entry frame must have a valid fp.
return fp_safe && is_entry_frame_valid(thread);
} else if (is_optimized_entry_frame()) {
return fp_safe;
}

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

return thread->is_in_stack_range_excl(jcw, (address)sender.fp());
} else if (sender_blob->is_optimized_entry_blob()) {
return false;
}

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

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

bool frame::optimized_entry_frame_is_first() const {
ShouldNotCallThis();
return false;
assert(is_optimized_entry_frame(), "must be optimzed entry frame");
OptimizedEntryBlob* blob = _cb->as_optimized_entry_blob();
JavaFrameAnchor* jfa = blob->jfa_for_frame(*this);
return jfa->last_Java_sp() == NULL;
}

frame frame::sender_for_optimized_entry_frame(RegisterMap* map) const {
ShouldNotCallThis();
return {};
assert(map != NULL, "map must be set");
OptimizedEntryBlob* blob = _cb->as_optimized_entry_blob();
// Java frame called from C; skip all C frames and return top C
// frame of that chunk as the sender
JavaFrameAnchor* jfa = blob->jfa_for_frame(*this);
assert(!optimized_entry_frame_is_first(), "must have a frame anchor to go back to");
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
// Since we are walking the stack now this nested anchor is obviously walkable
// even if it wasn't when it was stacked.
if (!jfa->walkable()) {
// Capture _last_Java_pc (if needed) and mark anchor walkable.
jfa->capture_last_Java_pc();
}
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());

return fr;
}

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

if (is_entry_frame())
return sender_for_entry_frame(map);
if (is_optimized_entry_frame())
return sender_for_optimized_entry_frame(map);
if (is_interpreted_frame())
return sender_for_interpreter_frame(map);
assert(_cb == CodeCache::find_blob(pc()),"Must be the same");
@@ -2075,7 +2075,7 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
cbz(value, done); // Use NULL as-is.

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

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

0 comments on commit 9e9ba2e

Please sign in to comment.