< prev index next >
src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp
Print this page
rev 9429 : 8143072: Port JVMCI to AArch64
Summary: AArch64-specific code for JVMCI
Reviewed-by: duke
*** 37,50 ****
#include "runtime/vframeArray.hpp"
#include "vmreg_aarch64.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
! #ifdef COMPILER2
#include "adfiles/ad_aarch64.hpp"
#include "opto/runtime.hpp"
#endif
#ifdef BUILTIN_SIM
#include "../../../../../../simulator/simulator.hpp"
#endif
--- 37,53 ----
#include "runtime/vframeArray.hpp"
#include "vmreg_aarch64.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
! #if defined(COMPILER2) || INCLUDE_JVMCI
#include "adfiles/ad_aarch64.hpp"
#include "opto/runtime.hpp"
#endif
+ #if INCLUDE_JVMCI
+ #include "jvmci/jvmciJavaClasses.hpp"
+ #endif
#ifdef BUILTIN_SIM
#include "../../../../../../simulator/simulator.hpp"
#endif
*** 107,124 ****
reg_save_size = return_off + 2};
};
OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
! #ifdef COMPILER2
if (save_vectors) {
// Save upper half of vector registers
int vect_words = 32 * 8 / wordSize;
additional_frame_words += vect_words;
}
#else
! assert(!save_vectors, "vectors are generated only by C2");
#endif
int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
reg_save_size*BytesPerInt, 16);
// OopMap frame size is in compiler stack slots (jint's) not bytes or words
--- 110,127 ----
reg_save_size = return_off + 2};
};
OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
! #if defined(COMPILER2) || INCLUDE_JVMCI
if (save_vectors) {
// Save upper half of vector registers
int vect_words = 32 * 8 / wordSize;
additional_frame_words += vect_words;
}
#else
! assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
#endif
int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
reg_save_size*BytesPerInt, 16);
// OopMap frame size is in compiler stack slots (jint's) not bytes or words
*** 164,174 ****
return oop_map;
}
void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
#ifndef COMPILER2
! assert(!restore_vectors, "vectors are generated only by C2");
#endif
__ pop_CPU_state(restore_vectors);
__ leave();
}
--- 167,177 ----
return oop_map;
}
void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
#ifndef COMPILER2
! assert(!restore_vectors, "vectors are generated only by C2 and JVMCI");
#endif
__ pop_CPU_state(restore_vectors);
__ leave();
}
*** 545,554 ****
--- 548,569 ----
// Will jump to the compiled code just as if compiled code was doing it.
// Pre-load the register-jump target early, to schedule it better.
__ ldr(rscratch1, Address(rmethod, in_bytes(Method::from_compiled_offset())));
+ #if INCLUDE_JVMCI
+ if (EnableJVMCI) {
+ // check if this call should be routed towards a specific entry point
+ __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+ Label no_alternative_target;
+ __ cbz(rscratch2, no_alternative_target);
+ __ mov(rscratch1, rscratch2);
+ __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+ __ bind(no_alternative_target);
+ }
+ #endif // INCLUDE_JVMCI
+
// Now generate the shuffle code.
for (int i = 0; i < total_args_passed; i++) {
if (sig_bt[i] == T_VOID) {
assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
continue;
*** 2235,2245 ****
//------------------------------generate_deopt_blob----------------------------
void SharedRuntime::generate_deopt_blob() {
// Allocate space for the code
ResourceMark rm;
// Setup code generation tools
! CodeBuffer buffer("deopt_blob", 2048, 1024);
MacroAssembler* masm = new MacroAssembler(&buffer);
int frame_size_in_words;
OopMap* map = NULL;
OopMapSet *oop_maps = new OopMapSet();
--- 2250,2266 ----
//------------------------------generate_deopt_blob----------------------------
void SharedRuntime::generate_deopt_blob() {
// Allocate space for the code
ResourceMark rm;
// Setup code generation tools
! int pad = 0;
! #if INCLUDE_JVMCI
! if (EnableJVMCI) {
! pad += 512; // Increase the buffer size when compiling for JVMCI
! }
! #endif
! CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
MacroAssembler* masm = new MacroAssembler(&buffer);
int frame_size_in_words;
OopMap* map = NULL;
OopMapSet *oop_maps = new OopMapSet();
*** 2292,2311 ****
--- 2313,2376 ----
// Normal deoptimization. Save exec mode for unpack_frames.
__ movw(rcpool, Deoptimization::Unpack_deopt); // callee-saved
__ b(cont);
int reexecute_offset = __ pc() - start;
+ #if defined(INCLUDE_JVMCI) && !defined(COMPILER1)
+ if (EnableJVMCI && UseJVMCICompiler) {
+ // JVMCI does not use this kind of deoptimization
+ __ should_not_reach_here();
+ }
+ #endif
// Reexecute case
// return address is the pc describes what bci to do re-execute at
// No need to update map as each call to save_live_registers will produce identical oopmap
(void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
__ movw(rcpool, Deoptimization::Unpack_reexecute); // callee-saved
__ b(cont);
+ #if INCLUDE_JVMCI
+ Label after_fetch_unroll_info_call;
+ int implicit_exception_uncommon_trap_offset = 0;
+ int uncommon_trap_offset = 0;
+
+ if (EnableJVMCI) {
+ implicit_exception_uncommon_trap_offset = __ pc() - start;
+
+ __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+ __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+
+ uncommon_trap_offset = __ pc() - start;
+
+ // Save everything in sight.
+ RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+ // fetch_unroll_info needs to call last_java_frame()
+ Label retaddr;
+ __ set_last_Java_frame(sp, noreg, retaddr, rscratch1);
+
+ __ ldrw(c_rarg1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
+ __ movw(rscratch1, -1);
+ __ strw(rscratch1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
+
+ __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute);
+ __ mov(c_rarg0, rthread);
+ __ lea(rscratch1,
+ RuntimeAddress(CAST_FROM_FN_PTR(address,
+ Deoptimization::uncommon_trap)));
+ __ blrt(rscratch1, 2, 0, MacroAssembler::ret_type_integral);
+ __ bind(retaddr);
+ oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
+
+ __ reset_last_Java_frame(false, false);
+
+ __ b(after_fetch_unroll_info_call);
+ } // EnableJVMCI
+ #endif // INCLUDE_JVMCI
+
int exception_offset = __ pc() - start;
// Prolog for exception case
// all registers are dead at this entry point, except for r0, and
*** 2393,2403 ****
// find any register it might need.
oop_maps->add_gc_map(__ pc() - start, map);
__ reset_last_Java_frame(false, true);
! // Load UnrollBlock* into rdi
__ mov(r5, r0);
__ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
Label noException;
__ cmpw(rcpool, Deoptimization::Unpack_exception); // Was exception pending?
--- 2458,2474 ----
// find any register it might need.
oop_maps->add_gc_map(__ pc() - start, map);
__ reset_last_Java_frame(false, true);
! #if INCLUDE_JVMCI
! if (EnableJVMCI) {
! __ bind(after_fetch_unroll_info_call);
! }
! #endif
!
! // Load UnrollBlock* into r5
__ mov(r5, r0);
__ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
Label noException;
__ cmpw(rcpool, Deoptimization::Unpack_exception); // Was exception pending?
*** 2545,2555 ****
// Make sure all code is generated
masm->flush();
_deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
_deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
!
#ifdef BUILTIN_SIM
if (NotifySimulator) {
unsigned char *base = _deopt_blob->code_begin();
simulator->notifyRelocate(start, base - start);
}
--- 2616,2631 ----
// Make sure all code is generated
masm->flush();
_deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
_deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
! #if INCLUDE_JVMCI
! if (EnableJVMCI) {
! _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
! _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
! }
! #endif
#ifdef BUILTIN_SIM
if (NotifySimulator) {
unsigned char *base = _deopt_blob->code_begin();
simulator->notifyRelocate(start, base - start);
}
*** 2558,2568 ****
uint SharedRuntime::out_preserve_stack_slots() {
return 0;
}
! #ifdef COMPILER2
//------------------------------generate_uncommon_trap_blob--------------------
void SharedRuntime::generate_uncommon_trap_blob() {
// Allocate space for the code
ResourceMark rm;
// Setup code generation tools
--- 2634,2644 ----
uint SharedRuntime::out_preserve_stack_slots() {
return 0;
}
! #if defined(COMPILER2) || INCLUDE_JVMCI
//------------------------------generate_uncommon_trap_blob--------------------
void SharedRuntime::generate_uncommon_trap_blob() {
// Allocate space for the code
ResourceMark rm;
// Setup code generation tools
*** 2941,2951 ****
// frame_size_words or bytes??
return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
}
! #ifdef COMPILER2
// This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
//
//------------------------------generate_exception_blob---------------------------
// creates exception blob at the end
// Using exception blob, this code is jumped from a compiled method.
--- 3017,3027 ----
// frame_size_words or bytes??
return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
}
! #if defined(COMPILER2) || INCLUDE_JVMCI
// This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
//
//------------------------------generate_exception_blob---------------------------
// creates exception blob at the end
// Using exception blob, this code is jumped from a compiled method.
< prev index next >