< prev index next >
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
Print this page
@@ -41,10 +41,13 @@
#endif
#ifdef SHARK
#include "compiler/compileBroker.hpp"
#include "shark/sharkCompiler.hpp"
#endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
#define __ masm->
class RegisterSaver {
@@ -758,17 +761,15 @@
__ cmp(pc_reg, temp_reg);
__ cmp_and_brx_short(pc_reg, temp_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ bind(L_fail);
}
-void AdapterGenerator::gen_i2c_adapter(
- int total_args_passed,
+void AdapterGenerator::gen_i2c_adapter(int total_args_passed,
// VMReg max_arg,
int comp_args_on_stack, // VMRegStackSlots
const BasicType *sig_bt,
const VMRegPair *regs) {
-
// Generate an I2C adapter: adjust the I-frame to make space for the C-frame
// layout. Lesp was saved by the calling I-frame and will be restored on
// return. Meanwhile, outgoing arg space is all owned by the callee
// C-frame, so we can mangle it at will. After adjusting the frame size,
// hoist register arguments and repack other args according to the compiled
@@ -988,10 +989,25 @@
}
}
// Jump to the compiled code just as if compiled code was doing it.
__ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3);
+#if INCLUDE_JVMCI
+ if (EnableJVMCI) {
+ // check if this call should be routed towards a specific entry point
+ __ ld(Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), G1);
+ __ cmp(G0, G1);
+ Label no_alternative_target;
+ __ br(Assembler::equal, false, Assembler::pn, no_alternative_target);
+ __ delayed()->nop();
+
+ __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset()), G3);
+ __ st(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+
+ __ bind(no_alternative_target);
+ }
+#endif // INCLUDE_JVMCI
// 6243940 We might end up in handle_wrong_method if
// the callee is deoptimized as we race thru here. If that
// happens we don't want to take a safepoint because the
// caller frame will look interpreted and arguments are now
@@ -1004,23 +1020,30 @@
__ st_ptr(G5_method, callee_target_addr);
__ jmpl(G3, 0, G0);
__ delayed()->nop();
}
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+ int total_args_passed,
+ int comp_args_on_stack,
+ const BasicType *sig_bt,
+ const VMRegPair *regs) {
+ AdapterGenerator agen(masm);
+ agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
+}
+
// ---------------------------------------------------------------
AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
int total_args_passed,
// VMReg max_arg,
int comp_args_on_stack, // VMRegStackSlots
const BasicType *sig_bt,
const VMRegPair *regs,
AdapterFingerPrint* fingerprint) {
address i2c_entry = __ pc();
- AdapterGenerator agen(masm);
-
- agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
+ gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
// -------------------------------------------------------------------------
// Generate a C2I adapter. On entry we know G5 holds the Method*. The
// args start out packed in the compiled layout. They need to be unpacked
@@ -1061,11 +1084,11 @@
__ delayed()->nop();
}
address c2i_entry = __ pc();
-
+ AdapterGenerator agen(masm);
agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, L_skip_fixup);
__ flush();
return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
@@ -2914,10 +2937,15 @@
#ifdef ASSERT
if (UseStackBanging) {
pad += StackShadowPages*16 + 32;
}
#endif
+#if INCLUDE_JVMCI
+ if (EnableJVMCI) {
+ pad += 1000; // Increase the buffer size when compiling for JVMCI
+ }
+#endif
#ifdef _LP64
CodeBuffer buffer("deopt_blob", 2100+pad, 512);
#else
// Measured 8/7/03 at 1212 in 32bit debug build (no VerifyThread)
// Measured 8/7/03 at 1396 in 32bit debug build (VerifyThread)
@@ -2980,10 +3008,49 @@
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
__ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
+
+#if INCLUDE_JVMCI
+ Label after_fetch_unroll_info_call;
+ int implicit_exception_uncommon_trap_offset = 0;
+ int uncommon_trap_offset = 0;
+
+ if (EnableJVMCI) {
+ masm->block_comment("BEGIN implicit_exception_uncommon_trap");
+ implicit_exception_uncommon_trap_offset = __ offset() - start;
+
+ __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()), O7);
+ __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+ __ add(O7, -8, O7);
+
+ uncommon_trap_offset = __ offset() - start;
+
+ // Save everything in sight.
+ (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
+ __ set_last_Java_frame(SP, NULL);
+
+ __ ld(G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()), O1);
+ __ sub(G0, 1, L1);
+ __ st(L1, G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()));
+
+ __ mov((int32_t)Deoptimization::Unpack_reexecute, L0deopt_mode);
+ __ mov(G2_thread, O0);
+ __ call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap));
+ __ delayed()->nop();
+ oop_maps->add_gc_map( __ offset()-start, map->deep_copy());
+ __ get_thread();
+ __ add(O7, 8, O7);
+ __ reset_last_Java_frame();
+
+ __ ba(after_fetch_unroll_info_call);
+ __ delayed()->nop(); // Delay slot
+ masm->block_comment("END implicit_exception_uncommon_trap");
+ } // EnableJVMCI
+#endif // INCLUDE_JVMCI
+
int exception_offset = __ offset() - start;
// restore G2, the trampoline destroyed it
__ get_thread();
@@ -3002,10 +3069,11 @@
// Vanilla deoptimization with an exception pending in exception_oop
//
int exception_in_tls_offset = __ offset() - start;
// No need to update oop_map as each call to save_live_registers will produce identical oopmap
+ // Opens a new stack frame
(void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
// Restore G2_thread
__ get_thread();
@@ -3033,11 +3101,16 @@
//
// Reexecute entry, similar to c2 uncommon trap
//
int reexecute_offset = __ offset() - start;
-
+#if INCLUDE_JVMCI && !defined(COMPILER1)
+ if (EnableJVMCI && UseJVMCICompiler) {
+ // JVMCI does not use this kind of deoptimization
+ __ should_not_reach_here();
+ }
+#endif
// No need to update oop_map as each call to save_live_registers will produce identical oopmap
(void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
__ mov(Deoptimization::Unpack_reexecute, L0deopt_mode);
@@ -3057,10 +3130,15 @@
__ mov(L7_thread_cache, G2_thread);
__ reset_last_Java_frame();
+#if INCLUDE_JVMCI
+ if (EnableJVMCI) {
+ __ bind(after_fetch_unroll_info_call);
+ }
+#endif
// NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
// so this move will survive
__ mov(L0deopt_mode, G4deopt_mode);
@@ -3122,10 +3200,16 @@
__ delayed()->restore();
masm->flush();
_deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_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 COMPILER2
//------------------------------generate_uncommon_trap_blob--------------------
< prev index next >