--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Mon Jul 23 13:04:59 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Tue Jul 24 10:51:00 2012 -0700
@@ -44,8 +44,10 @@
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
+#define STOP(error) stop(error)
#else
#define BLOCK_COMMENT(str) block_comment(str)
+#define STOP(error) block_comment(error); stop(error)
#endif
// Convert the raw encoding form into the form expected by the
@@ -992,7 +994,7 @@
save_frame(0); // to avoid clobbering O0
ld_ptr(pc_addr, L0);
br_null_short(L0, Assembler::pt, PcOk);
- stop("last_Java_pc not zeroed before leaving Java");
+ STOP("last_Java_pc not zeroed before leaving Java");
bind(PcOk);
// Verify that flags was zeroed on return to Java
@@ -1001,7 +1003,7 @@
tst(L0);
br(Assembler::zero, false, Assembler::pt, FlagsOk);
delayed() -> restore();
- stop("flags not zeroed before leaving Java");
+ STOP("flags not zeroed before leaving Java");
bind(FlagsOk);
#endif /* ASSERT */
//
@@ -1021,7 +1023,7 @@
andcc(last_java_sp, 0x01, G0);
br(Assembler::notZero, false, Assembler::pt, StackOk);
delayed()->nop();
- stop("Stack Not Biased in set_last_Java_frame");
+ STOP("Stack Not Biased in set_last_Java_frame");
bind(StackOk);
#endif // ASSERT
assert( last_java_sp != G4_scratch, "bad register usage in set_last_Java_frame");
@@ -1650,23 +1652,28 @@
void RegistersForDebugging::print(outputStream* s) {
+ FlagSetting fs(Debugging, true);
int j;
- for ( j = 0; j < 8; ++j )
- if ( j != 6 ) s->print_cr("i%d = 0x%.16lx", j, i[j]);
- else s->print_cr( "fp = 0x%.16lx", i[j]);
- s->cr();
-
- for ( j = 0; j < 8; ++j )
- s->print_cr("l%d = 0x%.16lx", j, l[j]);
+ for (j = 0; j < 8; ++j) {
+ if (j != 6) { s->print("i%d = ", j); os::print_location(s, i[j]); }
+ else { s->print( "fp = " ); os::print_location(s, i[j]); }
+ }
s->cr();
- for ( j = 0; j < 8; ++j )
- if ( j != 6 ) s->print_cr("o%d = 0x%.16lx", j, o[j]);
- else s->print_cr( "sp = 0x%.16lx", o[j]);
+ for (j = 0; j < 8; ++j) {
+ s->print("l%d = ", j); os::print_location(s, l[j]);
+ }
s->cr();
- for ( j = 0; j < 8; ++j )
- s->print_cr("g%d = 0x%.16lx", j, g[j]);
+ for (j = 0; j < 8; ++j) {
+ if (j != 6) { s->print("o%d = ", j); os::print_location(s, o[j]); }
+ else { s->print( "sp = " ); os::print_location(s, o[j]); }
+ }
+ s->cr();
+
+ for (j = 0; j < 8; ++j) {
+ s->print("g%d = ", j); os::print_location(s, g[j]);
+ }
s->cr();
// print out floats with compression
@@ -2020,8 +2027,8 @@
char* b = new char[1024];
sprintf(b, "untested: %s", what);
- if ( ShowMessageBoxOnError ) stop(b);
- else warn(b);
+ if (ShowMessageBoxOnError) { STOP(b); }
+ else { warn(b); }
}
@@ -2998,26 +3005,60 @@
}
+// virtual method calling
+void MacroAssembler::lookup_virtual_method(Register recv_klass,
+ RegisterOrConstant vtable_index,
+ Register method_result) {
+ assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
+ Register sethi_temp = method_result;
+ const int base = (instanceKlass::vtable_start_offset() * wordSize +
+ // method pointer offset within the vtable entry:
+ vtableEntry::method_offset_in_bytes());
+ RegisterOrConstant vtable_offset = vtable_index;
+ // Each of the following three lines potentially generates an instruction.
+ // But the total number of address formation instructions will always be
+ // at most two, and will often be zero. In any case, it will be optimal.
+ // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x).
+ // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t).
+ vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size() * wordSize), vtable_offset);
+ vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp);
+ Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp));
+ ld_ptr(vtable_entry_addr, method_result);
+}
+
+
void MacroAssembler::check_klass_subtype(Register sub_klass,
Register super_klass,
Register temp_reg,
Register temp2_reg,
Label& L_success) {
- Label L_failure, L_pop_to_failure;
- check_klass_subtype_fast_path(sub_klass, super_klass,
- temp_reg, temp2_reg,
- &L_success, &L_failure, NULL);
Register sub_2 = sub_klass;
Register sup_2 = super_klass;
if (!sub_2->is_global()) sub_2 = L0;
if (!sup_2->is_global()) sup_2 = L1;
-
- save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
+ bool did_save = false;
+ if (temp_reg == noreg || temp2_reg == noreg) {
+ temp_reg = L2;
+ temp2_reg = L3;
+ save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
+ sub_klass = sub_2;
+ super_klass = sup_2;
+ did_save = true;
+ }
+ Label L_failure, L_pop_to_failure, L_pop_to_success;
+ check_klass_subtype_fast_path(sub_klass, super_klass,
+ temp_reg, temp2_reg,
+ (did_save ? &L_pop_to_success : &L_success),
+ (did_save ? &L_pop_to_failure : &L_failure), NULL);
+
+ if (!did_save)
+ save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
check_klass_subtype_slow_path(sub_2, sup_2,
L2, L3, L4, L5,
NULL, &L_pop_to_failure);
// on success:
+ bind(L_pop_to_success);
restore();
ba_short(L_success);
@@ -3234,54 +3275,6 @@
}
-void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
- Register temp_reg,
- Label& wrong_method_type) {
- assert_different_registers(mtype_reg, mh_reg, temp_reg);
- // compare method type against that of the receiver
- RegisterOrConstant mhtype_offset = delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg);
- load_heap_oop(mh_reg, mhtype_offset, temp_reg);
- cmp_and_brx_short(temp_reg, mtype_reg, Assembler::notEqual, Assembler::pn, wrong_method_type);
-}
-
-
-// A method handle has a "vmslots" field which gives the size of its
-// argument list in JVM stack slots. This field is either located directly
-// in every method handle, or else is indirectly accessed through the
-// method handle's MethodType. This macro hides the distinction.
-void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
- Register temp_reg) {
- assert_different_registers(vmslots_reg, mh_reg, temp_reg);
- // load mh.type.form.vmslots
- Register temp2_reg = vmslots_reg;
- load_heap_oop(Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg);
- load_heap_oop(Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg);
- ld( Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
-}
-
-
-void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg, bool emit_delayed_nop) {
- assert(mh_reg == G3_method_handle, "caller must put MH object in G3");
- assert_different_registers(mh_reg, temp_reg);
-
- // pick out the interpreted side of the handler
- // NOTE: vmentry is not an oop!
- ld_ptr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
-
- // off we go...
- ld_ptr(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes(), temp_reg);
- jmp(temp_reg, 0);
-
- // for the various stubs which take control at this point,
- // see MethodHandles::generate_method_handle_stub
-
- // Some callers can fill the delay slot.
- if (emit_delayed_nop) {
- delayed()->nop();
- }
-}
-
-
RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot,
Register temp_reg,
int extra_slot_offset) {
@@ -3914,7 +3907,7 @@
ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t2);
or3(t1, t2, t3);
cmp_and_br_short(t1, t2, Assembler::greaterEqual, Assembler::pn, next);
- stop("assert(top >= start)");
+ STOP("assert(top >= start)");
should_not_reach_here();
bind(next);
@@ -3922,13 +3915,13 @@
ld_ptr(G2_thread, in_bytes(JavaThread::tlab_end_offset()), t2);
or3(t3, t2, t3);
cmp_and_br_short(t1, t2, Assembler::lessEqual, Assembler::pn, next2);
- stop("assert(top <= end)");
+ STOP("assert(top <= end)");
should_not_reach_here();
bind(next2);
and3(t3, MinObjAlignmentInBytesMask, t3);
cmp_and_br_short(t3, 0, Assembler::lessEqual, Assembler::pn, ok);
- stop("assert(aligned)");
+ STOP("assert(aligned)");
should_not_reach_here();
bind(ok);
@@ -3976,7 +3969,7 @@
btst(MinObjAlignmentInBytesMask, obj);
br(Assembler::zero, false, Assembler::pt, L);
delayed()->nop();
- stop("eden top is not properly aligned");
+ STOP("eden top is not properly aligned");
bind(L);
}
#endif // ASSERT
@@ -4013,7 +4006,7 @@
btst(MinObjAlignmentInBytesMask, top_addr);
br(Assembler::zero, false, Assembler::pt, L);
delayed()->nop();
- stop("eden top is not properly aligned");
+ STOP("eden top is not properly aligned");
bind(L);
}
#endif // ASSERT
@@ -4066,7 +4059,7 @@
btst(MinObjAlignmentInBytesMask, free);
br(Assembler::zero, false, Assembler::pt, L);
delayed()->nop();
- stop("updated TLAB free is not properly aligned");
+ STOP("updated TLAB free is not properly aligned");
bind(L);
}
#endif // ASSERT
@@ -4164,7 +4157,7 @@
ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t2);
sll_ptr(t2, LogHeapWordSize, t2);
cmp_and_br_short(t1, t2, Assembler::equal, Assembler::pt, ok);
- stop("assert(t1 == tlab_size)");
+ STOP("assert(t1 == tlab_size)");
should_not_reach_here();
bind(ok);