--- old/src/cpu/sparc/vm/assembler_sparc.cpp 2010-11-18 19:20:33.093573000 -0800 +++ new/src/cpu/sparc/vm/assembler_sparc.cpp 2010-11-18 19:20:32.888635000 -0800 @@ -893,10 +893,10 @@ #if defined(COMPILER2) && !defined(_LP64) // Save & restore possible 64-bit Long arguments in G-regs sllx(L0,32,G2); // Move old high G1 bits high in G2 - sllx(G1, 0,G1); // Clear current high G1 bits + slr(G1, 0,G1); // Clear current high G1 bits or3 (G1,G2,G1); // Recover 64-bit G1 sllx(L6,32,G2); // Move old high G4 bits high in G2 - sllx(G4, 0,G4); // Clear current high G4 bits + slr(G4, 0,G4); // Clear current high G4 bits or3 (G4,G2,G4); // Recover 64-bit G4 #endif restore(O0, 0, G2_thread); --- old/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp 2010-11-18 19:20:34.071320000 -0800 +++ new/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp 2010-11-18 19:20:33.873677000 -0800 @@ -424,7 +424,7 @@ Register pre_val_reg = pre_val()->as_register(); - ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); + ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*unaligned*/, false /*wide*/); if (__ is_in_wdisp16_range(_continuation)) { __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, pre_val_reg, _continuation); --- old/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp 2010-11-18 19:20:34.810504000 -0800 +++ new/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp 2010-11-18 19:20:34.613503000 -0800 @@ -151,3 +151,4 @@ static bool is_caller_save_register (LIR_Opr reg); static bool is_caller_save_register (Register r); + static int cpu_reg_range_reduction() { return 0; } --- old/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp 2010-11-18 19:20:35.483034000 -0800 +++ new/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp 2010-11-18 19:20:35.279427000 -0800 @@ -88,6 +88,13 @@ return false; } +#ifdef _LP64 + if (UseCompressedOops) { + if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false; + if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false; + } +#endif + if (dst->is_register()) { if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) { return !PatchALot; @@ -241,7 +248,7 @@ int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position int count_offset = java_lang_String:: count_offset_in_bytes(); - __ ld_ptr(str0, value_offset, tmp0); + __ load_heap_oop(str0, value_offset, tmp0); __ ld(str0, offset_offset, tmp2); __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); __ ld(str0, count_offset, str0); @@ -250,7 +257,7 @@ // str1 may be null add_debug_info_for_null_check_here(info); - __ ld_ptr(str1, value_offset, tmp1); + __ load_heap_oop(str1, value_offset, tmp1); __ add(tmp0, tmp2, tmp0); __ ld(str1, offset_offset, tmp2); @@ -754,7 +761,13 @@ void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { add_debug_info_for_null_check_here(op->info()); - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); +#ifdef _LP64 + if (UseCompressedOops) { + __ lduw(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); + __ decode_heap_oop(G3_scratch); + } else +#endif + __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); if (__ is_simm13(op->vtable_offset())) { __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method); } else { @@ -768,138 +781,17 @@ // the peephole pass fills the delay slot } - -// load with 32-bit displacement -int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) { - int load_offset = code_offset(); - if (Assembler::is_simm13(disp)) { - if (info != NULL) add_debug_info_for_null_check_here(info); - switch(ld_type) { - case T_BOOLEAN: // fall through - case T_BYTE : __ ldsb(s, disp, d); break; - case T_CHAR : __ lduh(s, disp, d); break; - case T_SHORT : __ ldsh(s, disp, d); break; - case T_INT : __ ld(s, disp, d); break; - case T_ADDRESS:// fall through - case T_ARRAY : // fall through - case T_OBJECT: __ ld_ptr(s, disp, d); break; - default : ShouldNotReachHere(); - } - } else { - __ set(disp, O7); - if (info != NULL) add_debug_info_for_null_check_here(info); - load_offset = code_offset(); - switch(ld_type) { - case T_BOOLEAN: // fall through - case T_BYTE : __ ldsb(s, O7, d); break; - case T_CHAR : __ lduh(s, O7, d); break; - case T_SHORT : __ ldsh(s, O7, d); break; - case T_INT : __ ld(s, O7, d); break; - case T_ADDRESS:// fall through - case T_ARRAY : // fall through - case T_OBJECT: __ ld_ptr(s, O7, d); break; - default : ShouldNotReachHere(); - } - } - if (ld_type == T_ARRAY || ld_type == T_OBJECT) __ verify_oop(d); - return load_offset; -} - - -// store with 32-bit displacement -void LIR_Assembler::store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info) { - if (Assembler::is_simm13(offset)) { - if (info != NULL) add_debug_info_for_null_check_here(info); - switch (type) { - case T_BOOLEAN: // fall through - case T_BYTE : __ stb(value, base, offset); break; - case T_CHAR : __ sth(value, base, offset); break; - case T_SHORT : __ sth(value, base, offset); break; - case T_INT : __ stw(value, base, offset); break; - case T_ADDRESS:// fall through - case T_ARRAY : // fall through - case T_OBJECT: __ st_ptr(value, base, offset); break; - default : ShouldNotReachHere(); - } - } else { - __ set(offset, O7); - if (info != NULL) add_debug_info_for_null_check_here(info); - switch (type) { - case T_BOOLEAN: // fall through - case T_BYTE : __ stb(value, base, O7); break; - case T_CHAR : __ sth(value, base, O7); break; - case T_SHORT : __ sth(value, base, O7); break; - case T_INT : __ stw(value, base, O7); break; - case T_ADDRESS:// fall through - case T_ARRAY : //fall through - case T_OBJECT: __ st_ptr(value, base, O7); break; - default : ShouldNotReachHere(); - } - } - // Note: Do the store before verification as the code might be patched! - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(value); -} - - -// load float with 32-bit displacement -void LIR_Assembler::load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) { - FloatRegisterImpl::Width w; - switch(ld_type) { - case T_FLOAT : w = FloatRegisterImpl::S; break; - case T_DOUBLE: w = FloatRegisterImpl::D; break; - default : ShouldNotReachHere(); - } - - if (Assembler::is_simm13(disp)) { - if (info != NULL) add_debug_info_for_null_check_here(info); - if (disp % BytesPerLong != 0 && w == FloatRegisterImpl::D) { - __ ldf(FloatRegisterImpl::S, s, disp + BytesPerWord, d->successor()); - __ ldf(FloatRegisterImpl::S, s, disp , d); - } else { - __ ldf(w, s, disp, d); - } - } else { - __ set(disp, O7); - if (info != NULL) add_debug_info_for_null_check_here(info); - __ ldf(w, s, O7, d); - } -} - - -// store float with 32-bit displacement -void LIR_Assembler::store(FloatRegister value, Register base, int offset, BasicType type, CodeEmitInfo *info) { - FloatRegisterImpl::Width w; - switch(type) { - case T_FLOAT : w = FloatRegisterImpl::S; break; - case T_DOUBLE: w = FloatRegisterImpl::D; break; - default : ShouldNotReachHere(); - } - - if (Assembler::is_simm13(offset)) { - if (info != NULL) add_debug_info_for_null_check_here(info); - if (w == FloatRegisterImpl::D && offset % BytesPerLong != 0) { - __ stf(FloatRegisterImpl::S, value->successor(), base, offset + BytesPerWord); - __ stf(FloatRegisterImpl::S, value , base, offset); - } else { - __ stf(w, value, base, offset); - } - } else { - __ set(offset, O7); - if (info != NULL) add_debug_info_for_null_check_here(info); - __ stf(w, value, O7, base); - } -} - - -int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned) { +int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) { int store_offset; if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { assert(!unaligned, "can't handle this"); // for offsets larger than a simm13 we setup the offset in O7 __ set(offset, O7); - store_offset = store(from_reg, base, O7, type); + store_offset = store(from_reg, base, O7, type, wide); } else { - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register()); + if (type == T_ARRAY || type == T_OBJECT) { + __ verify_oop(from_reg->as_register()); + } store_offset = code_offset(); switch (type) { case T_BOOLEAN: // fall through @@ -922,9 +814,23 @@ __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes); #endif break; - case T_ADDRESS:// fall through + case T_ADDRESS: + __ st_ptr(from_reg->as_register(), base, offset); + break; case T_ARRAY : // fall through - case T_OBJECT: __ st_ptr(from_reg->as_register(), base, offset); break; + case T_OBJECT: + { +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ encode_heap_oop(from_reg->as_register(), G3_scratch); + store_offset = code_offset(); + __ stw(G3_scratch, base, offset); + } else +#endif + __ st_ptr(from_reg->as_register(), base, offset); + break; + } + case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break; case T_DOUBLE: { @@ -946,8 +852,10 @@ } -int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type) { - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register()); +int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) { + if (type == T_ARRAY || type == T_OBJECT) { + __ verify_oop(from_reg->as_register()); + } int store_offset = code_offset(); switch (type) { case T_BOOLEAN: // fall through @@ -963,9 +871,22 @@ __ std(from_reg->as_register_hi(), base, disp); #endif break; - case T_ADDRESS:// fall through + case T_ADDRESS: + __ st_ptr(from_reg->as_register(), base, disp); + break; case T_ARRAY : // fall through - case T_OBJECT: __ st_ptr(from_reg->as_register(), base, disp); break; + case T_OBJECT: + { +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ encode_heap_oop(from_reg->as_register(), G3_scratch); + store_offset = code_offset(); + __ stw(G3_scratch, base, disp); + } else +#endif + __ st_ptr(from_reg->as_register(), base, disp); + break; + } case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break; case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break; default : ShouldNotReachHere(); @@ -974,14 +895,14 @@ } -int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned) { +int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) { int load_offset; if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { assert(base != O7, "destroying register"); assert(!unaligned, "can't handle this"); // for offsets larger than a simm13 we setup the offset in O7 __ set(offset, O7); - load_offset = load(base, O7, to_reg, type); + load_offset = load(base, O7, to_reg, type, wide); } else { load_offset = code_offset(); switch(type) { @@ -1018,9 +939,19 @@ #endif } break; - case T_ADDRESS:// fall through + case T_ADDRESS: __ ld_ptr(base, offset, to_reg->as_register()); break; case T_ARRAY : // fall through - case T_OBJECT: __ ld_ptr(base, offset, to_reg->as_register()); break; + case T_OBJECT: + { +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ lduw(base, offset, to_reg->as_register()); + __ decode_heap_oop(to_reg->as_register(), to_reg->as_register()); + } else +#endif + __ ld_ptr(base, offset, to_reg->as_register()); + break; + } case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break; case T_DOUBLE: { @@ -1036,23 +967,35 @@ } default : ShouldNotReachHere(); } - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register()); + if (type == T_ARRAY || type == T_OBJECT) { + __ verify_oop(to_reg->as_register()); + } } return load_offset; } -int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type) { +int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) { int load_offset = code_offset(); switch(type) { case T_BOOLEAN: // fall through - case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; - case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; - case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; - case T_INT : __ ld(base, disp, to_reg->as_register()); break; - case T_ADDRESS:// fall through + case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; + case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; + case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; + case T_INT : __ ld(base, disp, to_reg->as_register()); break; + case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break; case T_ARRAY : // fall through - case T_OBJECT: __ ld_ptr(base, disp, to_reg->as_register()); break; + case T_OBJECT: + { +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ lduw(base, disp, to_reg->as_register()); + __ decode_heap_oop(to_reg->as_register(), to_reg->as_register()); + } else +#endif + __ ld_ptr(base, disp, to_reg->as_register()); + break; + } case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break; case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break; case T_LONG : @@ -1066,61 +1009,17 @@ break; default : ShouldNotReachHere(); } - if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register()); + if (type == T_ARRAY || type == T_OBJECT) { + __ verify_oop(to_reg->as_register()); + } return load_offset; } - -// load/store with an Address -void LIR_Assembler::load(const Address& a, Register d, BasicType ld_type, CodeEmitInfo *info, int offset) { - load(a.base(), a.disp() + offset, d, ld_type, info); -} - - -void LIR_Assembler::store(Register value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) { - store(value, dest.base(), dest.disp() + offset, type, info); -} - - -// loadf/storef with an Address -void LIR_Assembler::load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info, int offset) { - load(a.base(), a.disp() + offset, d, ld_type, info); -} - - -void LIR_Assembler::store(FloatRegister value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) { - store(value, dest.base(), dest.disp() + offset, type, info); -} - - -// load/store with an Address -void LIR_Assembler::load(LIR_Address* a, Register d, BasicType ld_type, CodeEmitInfo *info) { - load(as_Address(a), d, ld_type, info); -} - - -void LIR_Assembler::store(Register value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) { - store(value, as_Address(dest), type, info); -} - - -// loadf/storef with an Address -void LIR_Assembler::load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) { - load(as_Address(a), d, ld_type, info); -} - - -void LIR_Assembler::store(FloatRegister value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) { - store(value, as_Address(dest), type, info); -} - - void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { LIR_Const* c = src->as_constant_ptr(); switch (c->type()) { case T_INT: - case T_FLOAT: - case T_ADDRESS: { + case T_FLOAT: { Register src_reg = O7; int value = c->as_jint_bits(); if (value == 0) { @@ -1132,6 +1031,18 @@ __ stw(src_reg, addr.base(), addr.disp()); break; } + case T_ADDRESS: { + Register src_reg = O7; + int value = c->as_jint_bits(); + if (value == 0) { + src_reg = G0; + } else { + __ set(value, O7); + } + Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); + __ st_ptr(src_reg, addr.base(), addr.disp()); + break; + } case T_OBJECT: { Register src_reg = O7; jobject2reg(c->as_jobject(), src_reg); @@ -1166,14 +1077,12 @@ } -void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) { +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { LIR_Const* c = src->as_constant_ptr(); LIR_Address* addr = dest->as_address_ptr(); Register base = addr->base()->as_pointer_register(); + int offset; - if (info != NULL) { - add_debug_info_for_null_check_here(info); - } switch (c->type()) { case T_INT: case T_FLOAT: @@ -1187,10 +1096,10 @@ } if (addr->index()->is_valid()) { assert(addr->disp() == 0, "must be zero"); - store(tmp, base, addr->index()->as_pointer_register(), type); + offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); } else { assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); - store(tmp, base, addr->disp(), type); + offset = store(tmp, base, addr->disp(), type, wide, false); } break; } @@ -1200,21 +1109,21 @@ assert(Assembler::is_simm13(addr->disp()) && Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses"); - Register tmp = O7; + LIR_Opr tmp = FrameMap::O7_opr; int value_lo = c->as_jint_lo_bits(); if (value_lo == 0) { - tmp = G0; + tmp = FrameMap::G0_opr; } else { __ set(value_lo, O7); } - store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT); + offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false); int value_hi = c->as_jint_hi_bits(); if (value_hi == 0) { - tmp = G0; + tmp = FrameMap::G0_opr; } else { __ set(value_hi, O7); } - store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT); + offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false); break; } case T_OBJECT: { @@ -1229,10 +1138,10 @@ // handle either reg+reg or reg+disp address if (addr->index()->is_valid()) { assert(addr->disp() == 0, "must be zero"); - store(tmp, base, addr->index()->as_pointer_register(), type); + offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); } else { assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); - store(tmp, base, addr->disp(), type); + offset = store(tmp, base, addr->disp(), type, wide, false); } break; @@ -1240,6 +1149,9 @@ default: Unimplemented(); } + if (info != NULL) { + add_debug_info_for_null_check(offset, info); + } } @@ -1324,7 +1236,8 @@ assert(to_reg->is_single_cpu(), "Must be a cpu register."); __ set(const_addrlit, O7); - load(O7, 0, to_reg->as_register(), T_INT); + __ ld(O7, 0, to_reg->as_register()); +// load(O7, 0, to_reg, T_INT, false /*wide*/, false /*unaligned*/); } } break; @@ -1417,7 +1330,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, - LIR_PatchCode patch_code, CodeEmitInfo* info, bool unaligned) { + LIR_PatchCode patch_code, CodeEmitInfo* info, bool unaligned, bool wide) { LIR_Address* addr = src_opr->as_address_ptr(); LIR_Opr to_reg = dest; @@ -1463,16 +1376,15 @@ assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); if (disp_reg == noreg) { - offset = load(src, disp_value, to_reg, type, unaligned); + offset = load(src, disp_value, to_reg, type, wide, unaligned); } else { assert(!unaligned, "can't handle this"); - offset = load(src, disp_reg, to_reg, type); + offset = load(src, disp_reg, to_reg, type, wide); } if (patch != NULL) { patching_epilog(patch, patch_code, src, info); } - if (info != NULL) add_debug_info_for_null_check(offset, info); } @@ -1506,7 +1418,7 @@ } bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; - load(addr.base(), addr.disp(), dest, dest->type(), unaligned); + load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned); } @@ -1518,7 +1430,7 @@ addr = frame_map()->address_for_slot(dest->double_stack_ix()); } bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; - store(from_reg, addr.base(), addr.disp(), from_reg->type(), unaligned); + store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned); } @@ -1566,7 +1478,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, - bool unaligned) { + bool unaligned, bool wide) { LIR_Address* addr = dest->as_address_ptr(); Register src = addr->base()->as_pointer_register(); @@ -1610,10 +1522,10 @@ assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); if (disp_reg == noreg) { - offset = store(from_reg, src, disp_value, type, unaligned); + offset = store(from_reg, src, disp_value, type, wide, unaligned); } else { assert(!unaligned, "can't handle this"); - offset = store(from_reg, src, disp_reg, type); + offset = store(from_reg, src, disp_reg, type, wide); } if (patch != NULL) { @@ -2172,13 +2084,13 @@ // make sure src and dst are non-null and load array length if (flags & LIR_OpArrayCopy::src_null_check) { __ tst(src); - __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); + __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); __ delayed()->nop(); } if (flags & LIR_OpArrayCopy::dst_null_check) { __ tst(dst); - __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); + __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); __ delayed()->nop(); } @@ -2220,10 +2132,19 @@ } if (flags & LIR_OpArrayCopy::type_check) { - __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); - __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); +#ifdef _LP64 + if (UseCompressedOops) { + // We don't need decode because we just need to compare + __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); + __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); + } else +#endif + { + __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); + __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); + } __ cmp(tmp, tmp2); - __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); + __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry()); __ delayed()->nop(); } @@ -2238,19 +2159,30 @@ // but not necessarily exactly of type default_type. Label known_ok, halt; jobject2reg(op->expected_type()->constant_encoding(), tmp); - __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); +#ifdef _LP64 + if (UseCompressedOops) { + __ encode_heap_oop(tmp, tmp); + __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); + } else +#endif + __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); if (basic_type != T_OBJECT) { __ cmp(tmp, tmp2); - __ br(Assembler::notEqual, false, Assembler::pn, halt); - __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); + __ brx(Assembler::notEqual, false, Assembler::pn, halt); +#ifdef _LP64 + if (UseCompressedOops) { + __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); + } else +#endif + __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); __ cmp(tmp, tmp2); - __ br(Assembler::equal, false, Assembler::pn, known_ok); + __ brx(Assembler::equal, false, Assembler::pn, known_ok); __ delayed()->nop(); } else { __ cmp(tmp, tmp2); - __ br(Assembler::equal, false, Assembler::pn, known_ok); + __ brx(Assembler::equal, false, Assembler::pn, known_ok); __ delayed()->cmp(src, dst); - __ br(Assembler::equal, false, Assembler::pn, known_ok); + __ brx(Assembler::equal, false, Assembler::pn, known_ok); __ delayed()->nop(); } __ bind(halt); @@ -2459,7 +2391,7 @@ Label next_test; Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - mdo_offset_bias); - load(recv_addr, tmp1, T_OBJECT); + __ ld_ptr(recv_addr, tmp1); __ br_notnull(tmp1, false, Assembler::pt, next_test); __ delayed()->nop(); __ st_ptr(recv, recv_addr); @@ -2551,7 +2483,7 @@ // get object class // not a safepoint as obj null check happens earlier - load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); + __ load_klass(obj, klass_RInfo); if (op->fast_check()) { assert_different_registers(klass_RInfo, k_RInfo); __ cmp(k_RInfo, klass_RInfo); @@ -2593,7 +2525,7 @@ __ set(mdo_offset_bias, tmp1); __ add(mdo, tmp1, mdo); } - load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); + __ load_klass(obj, recv); type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); // Jump over the failure case __ ba(false, *success); @@ -2662,11 +2594,12 @@ __ br_null(value, false, Assembler::pn, done); __ delayed()->nop(); } - load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); - load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); + add_debug_info_for_null_check_here(op->info_for_exception()); + __ load_klass(array, k_RInfo); + __ load_klass(value, klass_RInfo); // get instance klass - load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); + __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo); // perform the fast part of the checking logic __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL); @@ -2688,7 +2621,7 @@ __ set(mdo_offset_bias, tmp1); __ add(mdo, tmp1, mdo); } - load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); + __ load_klass(value, recv); type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); __ ba(false, done); __ delayed()->nop(); @@ -2771,7 +2704,13 @@ __ mov(new_value, t2); #ifdef _LP64 if (op->code() == lir_cas_obj) { - __ casx(addr, t1, t2); + if (UseCompressedOops) { + __ encode_heap_oop(t1, t1); + __ encode_heap_oop(t2, t2); + __ cas(addr, t1, t2); + } else { + __ casx(addr, t1, t2); + } } else #endif { @@ -2954,7 +2893,7 @@ } } } else { - load(Address(recv, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); + __ load_klass(recv, recv); Label update_done; type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done); // Receiver did not match any saved receiver and there is no empty row for it. @@ -3148,7 +3087,7 @@ } else { // use normal move for all other volatiles since they don't need // special handling to remain atomic. - move_op(src, dest, type, lir_patch_none, info, false, false); + move_op(src, dest, type, lir_patch_none, info, false, false, false); } } --- old/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp 2010-11-18 19:20:36.294714000 -0800 +++ new/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp 2010-11-18 19:20:36.096258000 -0800 @@ -37,33 +37,11 @@ // and then a load or store is emitted with ([O7] + [d]). // - // some load/store variants return the code_offset for proper positioning of debug info for null checks + int store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned); + int store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide); - // load/store with 32 bit displacement - int load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo* info = NULL); - void store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info = NULL); - - // loadf/storef with 32 bit displacement - void load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL); - void store(FloatRegister d, Register s1, int disp, BasicType st_type, CodeEmitInfo* info = NULL); - - // convienence methods for calling load/store with an Address - void load(const Address& a, Register d, BasicType ld_type, CodeEmitInfo* info = NULL, int offset = 0); - void store(Register d, const Address& a, BasicType st_type, CodeEmitInfo* info = NULL, int offset = 0); - void load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL, int offset = 0); - void store(FloatRegister d, const Address& a, BasicType st_type, CodeEmitInfo* info = NULL, int offset = 0); - - // convienence methods for calling load/store with an LIR_Address - void load(LIR_Address* a, Register d, BasicType ld_type, CodeEmitInfo* info = NULL); - void store(Register d, LIR_Address* a, BasicType st_type, CodeEmitInfo* info = NULL); - void load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL); - void store(FloatRegister d, LIR_Address* a, BasicType st_type, CodeEmitInfo* info = NULL); - - int store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned = false); - int store(LIR_Opr from_reg, Register base, Register disp, BasicType type); - - int load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned = false); - int load(Register base, Register disp, LIR_Opr to_reg, BasicType type); + int load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned); + int load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide); void monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no); --- old/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp 2010-11-18 19:20:36.959286000 -0800 +++ new/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp 2010-11-18 19:20:36.747808000 -0800 @@ -30,7 +30,7 @@ const Register temp_reg = G3_scratch; // Note: needs more testing of out-of-line vs. inline slow case verify_oop(receiver); - ld_ptr(receiver, oopDesc::klass_offset_in_bytes(), temp_reg); + load_klass(receiver, temp_reg); cmp(temp_reg, iCache); brx(Assembler::equal, true, Assembler::pt, L); delayed()->nop(); @@ -175,9 +175,22 @@ } else { set((intx)markOopDesc::prototype(), t1); } - st_ptr(t1 , obj, oopDesc::mark_offset_in_bytes ()); - st_ptr(klass, obj, oopDesc::klass_offset_in_bytes ()); - if (len->is_valid()) st(len , obj, arrayOopDesc::length_offset_in_bytes()); + st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); +#ifdef _LP64 + if (UseCompressedOops) { + // Save klass + mov(klass, t1); + encode_heap_oop(t1); + stw(t1, obj, oopDesc::klass_offset_in_bytes()); + } else +#endif + st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); + if (len->is_valid()) st(len, obj, arrayOopDesc::length_offset_in_bytes()); +#ifdef _LP64 + else if (UseCompressedOops) { + store_klass_gap(G0, obj); + } +#endif } @@ -225,7 +238,7 @@ Register t1, // temp register Register t2 // temp register ) { - const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes(); + const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; initialize_header(obj, klass, noreg, t1, t2); --- old/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp 2010-11-18 19:20:37.651299000 -0800 +++ new/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp 2010-11-18 19:20:37.435009000 -0800 @@ -600,7 +600,7 @@ // load the klass and check the has finalizer flag Label register_finalizer; Register t = O1; - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), t); + __ load_klass(O0, t); __ ld(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), t); __ set(JVM_ACC_HAS_FINALIZER, G3); __ andcc(G3, t, G0); --- old/src/cpu/x86/vm/c1_CodeStubs_x86.cpp 2010-11-18 19:20:38.407430000 -0800 +++ new/src/cpu/x86/vm/c1_CodeStubs_x86.cpp 2010-11-18 19:20:38.209513000 -0800 @@ -473,7 +473,7 @@ Register pre_val_reg = pre_val()->as_register(); - ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); + ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*unaligned*/, false /*wide*/); __ cmpptr(pre_val_reg, (int32_t) NULL_WORD); __ jcc(Assembler::equal, _continuation); --- old/src/cpu/x86/vm/c1_Defs_x86.hpp 2010-11-18 19:20:39.162287000 -0800 +++ new/src/cpu/x86/vm/c1_Defs_x86.hpp 2010-11-18 19:20:38.954782000 -0800 @@ -58,8 +58,8 @@ pd_nof_xmm_regs_linearscan = pd_nof_xmm_regs_frame_map, // number of registers visible to linear scan pd_first_cpu_reg = 0, pd_last_cpu_reg = NOT_LP64(5) LP64_ONLY(11), - pd_first_byte_reg = 2, - pd_last_byte_reg = 5, + pd_first_byte_reg = NOT_LP64(2) LP64_ONLY(0), + pd_last_byte_reg = NOT_LP64(5) LP64_ONLY(11), pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 7, pd_first_xmm_reg = pd_nof_cpu_regs_frame_map + pd_nof_fpu_regs_frame_map, --- old/src/cpu/x86/vm/c1_FrameMap_x86.cpp 2010-11-18 19:20:39.837402000 -0800 +++ new/src/cpu/x86/vm/c1_FrameMap_x86.cpp 2010-11-18 19:20:39.629261000 -0800 @@ -155,9 +155,11 @@ map_register( 6, r8); r8_opr = LIR_OprFact::single_cpu(6); map_register( 7, r9); r9_opr = LIR_OprFact::single_cpu(7); map_register( 8, r11); r11_opr = LIR_OprFact::single_cpu(8); - map_register( 9, r12); r12_opr = LIR_OprFact::single_cpu(9); - map_register(10, r13); r13_opr = LIR_OprFact::single_cpu(10); - map_register(11, r14); r14_opr = LIR_OprFact::single_cpu(11); + map_register( 9, r13); r13_opr = LIR_OprFact::single_cpu(9); + map_register(10, r14); r14_opr = LIR_OprFact::single_cpu(10); + // r12 is allocated conditionally. With compressed oops it holds + // the heapbase value and is not visible to the allocator. + map_register(11, r12); r12_opr = LIR_OprFact::single_cpu(11); // The unallocatable registers are at the end map_register(12, r10); r10_opr = LIR_OprFact::single_cpu(12); map_register(13, r15); r15_opr = LIR_OprFact::single_cpu(13); @@ -188,9 +190,9 @@ _caller_save_cpu_regs[6] = r8_opr; _caller_save_cpu_regs[7] = r9_opr; _caller_save_cpu_regs[8] = r11_opr; - _caller_save_cpu_regs[9] = r12_opr; - _caller_save_cpu_regs[10] = r13_opr; - _caller_save_cpu_regs[11] = r14_opr; + _caller_save_cpu_regs[9] = r13_opr; + _caller_save_cpu_regs[10] = r14_opr; + _caller_save_cpu_regs[11] = r12_opr; #endif // _LP64 --- old/src/cpu/x86/vm/c1_FrameMap_x86.hpp 2010-11-18 19:20:40.503393000 -0800 +++ new/src/cpu/x86/vm/c1_FrameMap_x86.hpp 2010-11-18 19:20:40.294031000 -0800 @@ -126,3 +126,15 @@ assert(i >= 0 && i < nof_caller_save_xmm_regs, "out of bounds"); return _caller_save_xmm_regs[i]; } + + // The amount of allocatable registers can change depending + // on whether compressed oops are on. + static int cpu_reg_range_reduction() { +#ifdef _LP64 + if (UseCompressedOops) { + // Reducing the allocatable range by 1 effectively excluding r12. + return 1; + } +#endif + return 0; + } --- old/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2010-11-18 19:20:41.245841000 -0800 +++ new/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2010-11-18 19:20:41.040607000 -0800 @@ -331,8 +331,8 @@ Register receiver = FrameMap::receiver_opr->as_register(); Register ic_klass = IC_Klass; const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); - - if (!VerifyOops) { + const bool do_post_padding = VerifyOops || UseCompressedOops; + if (!do_post_padding) { // insert some nops so that the verified entry point is aligned on CodeEntryAlignment while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { __ nop(); @@ -340,8 +340,8 @@ } int offset = __ offset(); __ inline_cache_check(receiver, IC_Klass); - assert(__ offset() % CodeEntryAlignment == 0 || VerifyOops, "alignment must be correct"); - if (VerifyOops) { + assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct"); + if (do_post_padding) { // force alignment after the cache check. // It's been verified to be aligned if !VerifyOops __ align(CodeEntryAlignment); @@ -547,14 +547,14 @@ __ movptr (rax, arg1->as_register()); // Get addresses of first characters from both Strings - __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); + __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes())); __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); // rbx, may be NULL add_debug_info_for_null_check_here(info); - __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); + __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); @@ -684,13 +684,18 @@ LIR_Const* c = src->as_constant_ptr(); switch (c->type()) { - case T_INT: - case T_ADDRESS: { + case T_INT: { assert(patch_code == lir_patch_none, "no patching handled here"); __ movl(dest->as_register(), c->as_jint()); break; } + case T_ADDRESS: { + assert(patch_code == lir_patch_none, "no patching handled here"); + __ movptr(dest->as_register(), c->as_jint()); + break; + } + case T_LONG: { assert(patch_code == lir_patch_none, "no patching handled here"); #ifdef _LP64 @@ -768,10 +773,13 @@ switch (c->type()) { case T_INT: // fall through case T_FLOAT: - case T_ADDRESS: __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); break; + case T_ADDRESS: + __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); + break; + case T_OBJECT: __ movoop(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jobject()); break; @@ -794,7 +802,7 @@ } } -void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) { +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { assert(src->is_constant(), "should not call otherwise"); assert(dest->is_address(), "should not call otherwise"); LIR_Const* c = src->as_constant_ptr(); @@ -804,14 +812,25 @@ switch (type) { case T_INT: // fall through case T_FLOAT: - case T_ADDRESS: __ movl(as_Address(addr), c->as_jint_bits()); break; + case T_ADDRESS: + __ movptr(as_Address(addr), c->as_jint_bits()); + break; + case T_OBJECT: // fall through case T_ARRAY: if (c->as_jobject() == NULL) { +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ movl(as_Address(addr), (int32_t)NULL_WORD); + } else { + __ movptr(as_Address(addr), NULL_WORD); + } +#else __ movptr(as_Address(addr), NULL_WORD); +#endif } else { if (is_literal_address(addr)) { ShouldNotReachHere(); @@ -819,8 +838,14 @@ } else { #ifdef _LP64 __ movoop(rscratch1, c->as_jobject()); - null_check_here = code_offset(); - __ movptr(as_Address_lo(addr), rscratch1); + if (UseCompressedOops && !wide) { + __ encode_heap_oop(rscratch1); + null_check_here = code_offset(); + __ movl(as_Address_lo(addr), rscratch1); + } else { + null_check_here = code_offset(); + __ movptr(as_Address_lo(addr), rscratch1); + } #else __ movoop(as_Address(addr), c->as_jobject()); #endif @@ -997,22 +1022,31 @@ } -void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool /* unaligned */) { +void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool /* unaligned */, bool wide) { LIR_Address* to_addr = dest->as_address_ptr(); PatchingStub* patch = NULL; +#ifdef _LP64 + Register compressed_src = rscratch1; +#endif + if (type == T_ARRAY || type == T_OBJECT) { __ verify_oop(src->as_register()); +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ movptr(compressed_src, src->as_register()); + __ encode_heap_oop(compressed_src); + } +#endif } + if (patch_code != lir_patch_none) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); Address toa = as_Address(to_addr); assert(toa.disp() != 0, "must have"); } - if (info != NULL) { - add_debug_info_for_null_check_here(info); - } + int null_check_here = code_offset(); switch (type) { case T_FLOAT: { if (src->is_single_xmm()) { @@ -1038,13 +1072,19 @@ break; } - case T_ADDRESS: // fall through case T_ARRAY: // fall through case T_OBJECT: // fall through #ifdef _LP64 - __ movptr(as_Address(to_addr), src->as_register()); + if (UseCompressedOops && !wide) { + __ movl(as_Address(to_addr), compressed_src); + } else { + __ movptr(as_Address(to_addr), src->as_register()); + } break; #endif // _LP64 + case T_ADDRESS: + __ movptr(as_Address(to_addr), src->as_register()); + break; case T_INT: __ movl(as_Address(to_addr), src->as_register()); break; @@ -1101,6 +1141,9 @@ default: ShouldNotReachHere(); } + if (info != NULL) { + add_debug_info_for_null_check(null_check_here, info); + } if (patch_code != lir_patch_none) { patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); @@ -1184,7 +1227,7 @@ } -void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool /* unaligned */) { +void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool /* unaligned */, bool wide) { assert(src->is_address(), "should not call otherwise"); assert(dest->is_register(), "should not call otherwise"); @@ -1238,13 +1281,19 @@ break; } - case T_ADDRESS: // fall through case T_OBJECT: // fall through case T_ARRAY: // fall through #ifdef _LP64 - __ movptr(dest->as_register(), from_addr); + if (UseCompressedOops && !wide) { + __ movl(dest->as_register(), from_addr); + } else { + __ movptr(dest->as_register(), from_addr); + } break; #endif // _L64 + case T_ADDRESS: + __ movptr(dest->as_register(), from_addr); + break; case T_INT: __ movl(dest->as_register(), from_addr); break; @@ -1339,6 +1388,11 @@ } if (type == T_ARRAY || type == T_OBJECT) { +#ifdef _LP64 + if (UseCompressedOops && !wide) { + __ decode_heap_oop(dest->as_register()); + } +#endif __ verify_oop(dest->as_register()); } } @@ -1678,7 +1732,7 @@ } else if (obj == klass_RInfo) { klass_RInfo = dst; } - if (k->is_loaded()) { + if (k->is_loaded() && LP64_ONLY(!UseCompressedOops) NOT_LP64(true)) { select_different_registers(obj, dst, k_RInfo, klass_RInfo); } else { Rtmp1 = op->tmp3()->as_register(); @@ -1715,21 +1769,26 @@ if (op->fast_check()) { // get object class // not a safepoint as obj null check happens earlier - if (k->is_loaded()) { #ifdef _LP64 + if (UseCompressedOops) { + __ load_klass(Rtmp1, obj); + __ cmpl(k_RInfo, Rtmp1); + } else { __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + } #else + if (k->is_loaded()) { __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); -#endif // _LP64 } else { __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); } +#endif __ jcc(Assembler::notEqual, *failure_target); // successful cast, fall through to profile or jump } else { // get object class // not a safepoint as obj null check happens earlier - __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ load_klass(klass_RInfo, obj); if (k->is_loaded()) { // See if we get an immediate positive hit #ifdef _LP64 @@ -1784,7 +1843,7 @@ Register mdo = klass_RInfo, recv = k_RInfo; __ bind(profile_cast_success); __ movoop(mdo, md->constant_encoding()); - __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); + __ load_klass(recv, obj); Label update_done; type_profile_helper(mdo, md, data, recv, success); __ jmp(*success); @@ -1848,10 +1907,10 @@ } add_debug_info_for_null_check_here(op->info_for_exception()); - __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); - __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); + __ load_klass(k_RInfo, array); + __ load_klass(klass_RInfo, value); - // get instance klass + // get instance klass (it's already uncompressed) __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); // perform the fast part of the checking logic __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); @@ -1870,7 +1929,7 @@ Register mdo = klass_RInfo, recv = k_RInfo; __ bind(profile_cast_success); __ movoop(mdo, md->constant_encoding()); - __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes())); + __ load_klass(recv, value); Label update_done; type_profile_helper(mdo, md, data, recv, &done); __ jmpb(done); @@ -1934,12 +1993,32 @@ assert(cmpval != newval, "cmp and new values must be in different registers"); assert(cmpval != addr, "cmp and addr must be in different registers"); assert(newval != addr, "new value and addr must be in different registers"); - if (os::is_MP()) { - __ lock(); - } + if ( op->code() == lir_cas_obj) { - __ cmpxchgptr(newval, Address(addr, 0)); - } else if (op->code() == lir_cas_int) { +#ifdef _LP64 + if (UseCompressedOops) { + __ mov(rscratch1, cmpval); + __ encode_heap_oop(cmpval); + __ mov(rscratch2, newval); + __ encode_heap_oop(rscratch2); + if (os::is_MP()) { + __ lock(); + } + __ cmpxchgl(rscratch2, Address(addr, 0)); + __ mov(cmpval, rscratch1); + } else +#endif + { + if (os::is_MP()) { + __ lock(); + } + __ cmpxchgptr(newval, Address(addr, 0)); + } + } else { + assert(op->code() == lir_cas_int, "lir_cas_int expected"); + if (os::is_MP()) { + __ lock(); + } __ cmpxchgl(newval, Address(addr, 0)); } #ifdef _LP64 @@ -3181,8 +3260,16 @@ } if (flags & LIR_OpArrayCopy::type_check) { - __ movptr(tmp, src_klass_addr); - __ cmpptr(tmp, dst_klass_addr); +#ifdef _LP64 + if (UseCompressedOops) { + __ movl(tmp, src_klass_addr); + __ cmpl(tmp, dst_klass_addr); + } else +#endif + { + __ movptr(tmp, src_klass_addr); + __ cmpptr(tmp, dst_klass_addr); + } __ jcc(Assembler::notEqual, *stub->entry()); } @@ -3197,13 +3284,31 @@ // but not necessarily exactly of type default_type. Label known_ok, halt; __ movoop(tmp, default_type->constant_encoding()); +#ifdef _LP64 + if (UseCompressedOops) { + __ encode_heap_oop(tmp); + } +#endif + if (basic_type != T_OBJECT) { - __ cmpptr(tmp, dst_klass_addr); +#ifdef _LP64 + if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); + else +#endif + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, halt); - __ cmpptr(tmp, src_klass_addr); +#ifdef _LP64 + if (UseCompressedOops) __ cmpl(tmp, src_klass_addr); + else +#endif + __ cmpptr(tmp, src_klass_addr); __ jcc(Assembler::equal, known_ok); } else { - __ cmpptr(tmp, dst_klass_addr); +#ifdef _LP64 + if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); + else +#endif + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::equal, known_ok); __ cmpptr(src, dst); __ jcc(Assembler::equal, known_ok); @@ -3332,7 +3437,7 @@ } } } else { - __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); + __ load_klass(recv, recv); Label update_done; type_profile_helper(mdo, md, data, recv, &update_done); // Receiver did not match any saved receiver and there is no empty row for it. --- old/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp 2010-11-18 19:20:42.210972000 -0800 +++ new/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp 2010-11-18 19:20:42.011150000 -0800 @@ -1139,9 +1139,12 @@ stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); } LIR_Opr reg = rlock_result(x); + LIR_Opr tmp3 = LIR_OprFact::illegalOpr; + if (!x->klass()->is_loaded() || LP64_ONLY(UseCompressedOops) NOT_LP64(false)) { + tmp3 = new_register(objectType); + } __ checkcast(reg, obj.result(), x->klass(), - new_register(objectType), new_register(objectType), - !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr, + new_register(objectType), new_register(objectType), tmp3, x->direct_compare(), info_for_exception, patching_info, stub, x->profiled_method(), x->profiled_bci()); } @@ -1158,9 +1161,12 @@ patching_info = state_for(x, x->state_before()); } obj.load_item(); + LIR_Opr tmp3 = LIR_OprFact::illegalOpr; + if (!x->klass()->is_loaded() || LP64_ONLY(UseCompressedOops) NOT_LP64(false)) { + tmp3 = new_register(objectType); + } __ instanceof(reg, obj.result(), x->klass(), - new_register(objectType), new_register(objectType), - !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr, + new_register(objectType), new_register(objectType), tmp3, x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); } --- old/src/cpu/x86/vm/c1_LinearScan_x86.hpp 2010-11-18 19:20:42.978076000 -0800 +++ new/src/cpu/x86/vm/c1_LinearScan_x86.hpp 2010-11-18 19:20:42.780213000 -0800 @@ -31,14 +31,16 @@ return reg_num < 6 || reg_num > 7; #else - // rsp and rbp, r10, r15 (numbers 6 ancd 7) are ignored + // rsp and rbp, r10, r15 (numbers [12,15]) are ignored + // r12 (number 11) is conditional on compressed oops. + assert(FrameMap::r12_opr->cpu_regnr() == 11, "wrong assumption below"); assert(FrameMap::r10_opr->cpu_regnr() == 12, "wrong assumption below"); assert(FrameMap::r15_opr->cpu_regnr() == 13, "wrong assumption below"); assert(FrameMap::rsp_opr->cpu_regnrLo() == 14, "wrong assumption below"); assert(FrameMap::rbp_opr->cpu_regnrLo() == 15, "wrong assumption below"); assert(reg_num >= 0, "invalid reg_num"); - return reg_num < 12 || reg_num > 15; + return reg_num < 12 - FrameMap::cpu_reg_range_reduction() || reg_num > 15; #endif // _LP64 } @@ -101,7 +103,7 @@ if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::byte_reg)) { assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only"); _first_reg = pd_first_byte_reg; - _last_reg = pd_last_byte_reg; + _last_reg = pd_last_byte_reg - FrameMap::cpu_reg_range_reduction(); return true; } else if ((UseSSE >= 1 && cur->type() == T_FLOAT) || (UseSSE >= 2 && cur->type() == T_DOUBLE)) { _first_reg = pd_first_xmm_reg; --- old/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp 2010-11-18 19:20:43.657230000 -0800 +++ new/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp 2010-11-18 19:20:43.445671000 -0800 @@ -145,11 +145,26 @@ // This assumes that all prototype bits fit in an int32_t movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype()); } +#ifdef _LP64 + if (UseCompressedOops) { // Take care not to kill klass + movptr(t1, klass); + encode_heap_oop_not_null(t1); + movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1); + } else +#endif + { + movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); + } - movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); if (len->is_valid()) { movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); } +#ifdef _LP64 + else if (UseCompressedOops) { + xorptr(t1, t1); + store_klass_gap(obj, t1); + } +#endif // _LP64 } @@ -220,7 +235,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) { assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, "con_size_in_bytes is not multiple of alignment"); - const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes(); + const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; initialize_header(obj, klass, noreg, t1, t2); @@ -307,13 +322,19 @@ // check against inline cache assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); int start_offset = offset(); - cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); +#ifdef _LP64 + if (UseCompressedOops) { + load_klass(rscratch1, receiver); + cmpptr(rscratch1, iCache); + } else +#endif + cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); // if icache check fails, then jump to runtime routine // Note: RECEIVER must still contain the receiver! jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); - assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); + assert(UseCompressedOops || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); } --- old/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2010-11-18 19:20:44.334631000 -0800 +++ new/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2010-11-18 19:20:44.131630000 -0800 @@ -1249,7 +1249,7 @@ // load the klass and check the has finalizer flag Label register_finalizer; Register t = rsi; - __ movptr(t, Address(rax, oopDesc::klass_offset_in_bytes())); + __ load_klass(t, rax); __ movl(t, Address(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(t, JVM_ACC_HAS_FINALIZER); __ jcc(Assembler::notZero, register_finalizer); --- old/src/share/vm/c1/c1_GraphBuilder.cpp 2010-11-18 19:20:45.102462000 -0800 +++ new/src/share/vm/c1/c1_GraphBuilder.cpp 2010-11-18 19:20:44.886971000 -0800 @@ -2786,7 +2786,7 @@ get = append(new UnsafeGetRaw(as_BasicType(local->type()), e, append(new Constant(new IntConstant(offset))), 0, - true)); + true /*unaligned*/, true /*wide*/)); } _state->store_local(index, get); } --- old/src/share/vm/c1/c1_Instruction.hpp 2010-11-18 19:20:45.928785000 -0800 +++ new/src/share/vm/c1/c1_Instruction.hpp 2010-11-18 19:20:45.727036000 -0800 @@ -2102,20 +2102,23 @@ LEAF(UnsafeGetRaw, UnsafeRawOp) private: - bool _may_be_unaligned; // For OSREntry + bool _may_be_unaligned, _is_wide; // For OSREntry public: - UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned) + UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned, bool is_wide = false) : UnsafeRawOp(basic_type, addr, false) { _may_be_unaligned = may_be_unaligned; + _is_wide = is_wide; } - UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned) + UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned, bool is_wide = false) : UnsafeRawOp(basic_type, base, index, log2_scale, false) { _may_be_unaligned = may_be_unaligned; + _is_wide = is_wide; } - bool may_be_unaligned() { return _may_be_unaligned; } + bool may_be_unaligned() { return _may_be_unaligned; } + bool is_wide() { return _is_wide; } }; --- old/src/share/vm/c1/c1_LIR.cpp 2010-11-18 19:20:46.750123000 -0800 +++ new/src/share/vm/c1/c1_LIR.cpp 2010-11-18 19:20:46.548441000 -0800 @@ -1737,6 +1737,8 @@ return "unaligned move"; case lir_move_volatile: return "volatile_move"; + case lir_move_wide: + return "wide_move"; default: ShouldNotReachHere(); return "illegal_op"; --- old/src/share/vm/c1/c1_LIR.hpp 2010-11-18 19:20:47.482789000 -0800 +++ new/src/share/vm/c1/c1_LIR.hpp 2010-11-18 19:20:47.280737000 -0800 @@ -980,6 +980,7 @@ lir_move_normal, lir_move_volatile, lir_move_unaligned, + lir_move_wide, lir_move_max_flag }; @@ -1927,7 +1928,22 @@ void move(LIR_Opr src, LIR_Opr dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, src, dst, dst->type(), lir_patch_none, info)); } void move(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info)); } void move(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info)); } - + void move_wide(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = NULL) { +#ifdef _LP64 + if (UseCompressedOops) { + append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info, lir_move_wide)); + } else +#endif + move(src, dst, info); + } + void move_wide(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) { +#ifdef _LP64 + if (UseCompressedOops) { + append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info, lir_move_wide)); + } else +#endif + move(src, dst, info); + } void volatile_move(LIR_Opr src, LIR_Opr dst, BasicType type, CodeEmitInfo* info = NULL, LIR_PatchCode patch_code = lir_patch_none) { append(new LIR_Op1(lir_move, src, dst, type, patch_code, info, lir_move_volatile)); } void oop2reg (jobject o, LIR_Opr reg) { append(new LIR_Op1(lir_move, LIR_OprFact::oopConst(o), reg)); } --- old/src/share/vm/c1/c1_LIRAssembler.cpp 2010-11-18 19:20:48.199856000 -0800 +++ new/src/share/vm/c1/c1_LIRAssembler.cpp 2010-11-18 19:20:48.000753000 -0800 @@ -471,7 +471,9 @@ volatile_move_op(op->in_opr(), op->result_opr(), op->type(), op->info()); } else { move_op(op->in_opr(), op->result_opr(), op->type(), - op->patch_code(), op->info(), op->pop_fpu_stack(), op->move_kind() == lir_move_unaligned); + op->patch_code(), op->info(), op->pop_fpu_stack(), + op->move_kind() == lir_move_unaligned, + op->move_kind() == lir_move_wide); } break; @@ -740,7 +742,7 @@ } -void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned) { +void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide) { if (src->is_register()) { if (dest->is_register()) { assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); @@ -749,7 +751,7 @@ assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); reg2stack(src, dest, type, pop_fpu_stack); } else if (dest->is_address()) { - reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, unaligned); + reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, unaligned, wide); } else { ShouldNotReachHere(); } @@ -772,13 +774,13 @@ const2stack(src, dest); } else if (dest->is_address()) { assert(patch_code == lir_patch_none, "no patching allowed here"); - const2mem(src, dest, type, info); + const2mem(src, dest, type, info, wide); } else { ShouldNotReachHere(); } } else if (src->is_address()) { - mem2reg(src, dest, type, patch_code, info, unaligned); + mem2reg(src, dest, type, patch_code, info, unaligned, wide); } else { ShouldNotReachHere(); --- old/src/share/vm/c1/c1_LIRAssembler.hpp 2010-11-18 19:20:48.881881000 -0800 +++ new/src/share/vm/c1/c1_LIRAssembler.hpp 2010-11-18 19:20:48.682601000 -0800 @@ -157,15 +157,17 @@ void const2reg (LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info); void const2stack(LIR_Opr src, LIR_Opr dest); - void const2mem (LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info); + void const2mem (LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide); void reg2stack (LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack); void reg2reg (LIR_Opr src, LIR_Opr dest); - void reg2mem (LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned); + void reg2mem (LIR_Opr src, LIR_Opr dest, BasicType type, + LIR_PatchCode patch_code, CodeEmitInfo* info, + bool pop_fpu_stack, bool unaligned, bool wide); void stack2reg (LIR_Opr src, LIR_Opr dest, BasicType type); void stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type); void mem2reg (LIR_Opr src, LIR_Opr dest, BasicType type, - LIR_PatchCode patch_code = lir_patch_none, - CodeEmitInfo* info = NULL, bool unaligned = false); + LIR_PatchCode patch_code, + CodeEmitInfo* info, bool unaligned, bool wide); void prefetchr (LIR_Opr src); void prefetchw (LIR_Opr src); @@ -203,7 +205,7 @@ void roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack); void move_op(LIR_Opr src, LIR_Opr result, BasicType type, - LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned); + LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide); void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); // info set for null exceptions void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op); --- old/src/share/vm/c1/c1_LIRGenerator.cpp 2010-11-18 19:20:49.633031000 -0800 +++ new/src/share/vm/c1/c1_LIRGenerator.cpp 2010-11-18 19:20:49.430167000 -0800 @@ -850,11 +850,11 @@ // MDO cells are intptr_t, so the data_reg width is arch-dependent. LIR_Opr data_reg = new_pointer_register(); LIR_Address* data_addr = new LIR_Address(md_reg, data_offset_reg, data_reg->type()); - __ move(LIR_OprFact::address(data_addr), data_reg); + __ move(data_addr, data_reg); // Use leal instead of add to avoid destroying condition codes on x86 LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT); __ leal(LIR_OprFact::address(fake_incr_value), data_reg); - __ move(data_reg, LIR_OprFact::address(data_addr)); + __ move(data_reg, data_addr); } } @@ -995,12 +995,12 @@ operand_for_instruction(phi)); LIR_Opr thread_reg = getThreadPointer(); - __ move(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT), - exceptionOopOpr()); - __ move(LIR_OprFact::oopConst(NULL), - new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT)); - __ move(LIR_OprFact::oopConst(NULL), - new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT)); + __ move_wide(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT), + exceptionOopOpr()); + __ move_wide(LIR_OprFact::oopConst(NULL), + new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT)); + __ move_wide(LIR_OprFact::oopConst(NULL), + new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT)); LIR_Opr result = new_register(T_OBJECT); __ move(exceptionOopOpr(), result); @@ -1071,7 +1071,7 @@ void LIRGenerator::do_Return(Return* x) { if (compilation()->env()->dtrace_method_probes()) { BasicTypeList signature; - signature.append(T_INT); // thread + signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread signature.append(T_OBJECT); // methodOop LIR_OprList* args = new LIR_OprList(); args->append(getThreadPointer()); @@ -1108,8 +1108,8 @@ info = state_for(x); } __ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), result, info); - __ move(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() + - klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result); + __ move_wide(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() + + klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result); } @@ -1117,7 +1117,7 @@ void LIRGenerator::do_currentThread(Intrinsic* x) { assert(x->number_of_arguments() == 0, "wrong type"); LIR_Opr reg = rlock_result(x); - __ load(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg); + __ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg); } @@ -1894,7 +1894,11 @@ if (x->may_be_unaligned() && (dst_type == T_LONG || dst_type == T_DOUBLE)) { __ unaligned_move(addr, reg); } else { - __ move(addr, reg); + if (dst_type == T_OBJECT && x->is_wide()) { + __ move_wide(addr, reg); + } else { + __ move(addr, reg); + } } } @@ -2273,7 +2277,7 @@ if (compilation()->env()->dtrace_method_probes()) { BasicTypeList signature; - signature.append(T_INT); // thread + signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread signature.append(T_OBJECT); // methodOop LIR_OprList* args = new LIR_OprList(); args->append(getThreadPointer()); @@ -2338,11 +2342,14 @@ } else { LIR_Address* addr = loc->as_address_ptr(); param->load_for_store(addr->type()); - if (addr->type() == T_LONG || addr->type() == T_DOUBLE) { - __ unaligned_move(param->result(), addr); - } else { - __ move(param->result(), addr); - } + if (addr->type() == T_OBJECT) { + __ move_wide(param->result(), addr); + } else + if (addr->type() == T_LONG || addr->type() == T_DOUBLE) { + __ unaligned_move(param->result(), addr); + } else { + __ move(param->result(), addr); + } } } @@ -2354,7 +2361,7 @@ } else { assert(loc->is_address(), "just checking"); receiver->load_for_store(T_OBJECT); - __ move(receiver->result(), loc); + __ move_wide(receiver->result(), loc->as_address_ptr()); } } } --- old/src/share/vm/c1/c1_LinearScan.cpp 2010-11-18 19:20:50.473725000 -0800 +++ new/src/share/vm/c1/c1_LinearScan.cpp 2010-11-18 19:20:50.267011000 -0800 @@ -1256,7 +1256,7 @@ int caller_save_registers[LinearScan::nof_regs]; int i; - for (i = 0; i < FrameMap::nof_caller_save_cpu_regs; i++) { + for (i = 0; i < FrameMap::nof_caller_save_cpu_regs - FrameMap::cpu_reg_range_reduction(); i++) { LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i); assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands"); assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); @@ -3540,7 +3540,7 @@ // invalidate all caller save registers at calls if (visitor.has_call()) { - for (j = 0; j < FrameMap::nof_caller_save_cpu_regs; j++) { + for (j = 0; j < FrameMap::nof_caller_save_cpu_regs - FrameMap::cpu_reg_range_reduction(); j++) { state_put(input_state, reg_num(FrameMap::caller_save_cpu_reg_at(j)), NULL); } for (j = 0; j < FrameMap::nof_caller_save_fpu_regs; j++) { @@ -5579,7 +5579,7 @@ _last_reg = pd_last_fpu_reg; } else { _first_reg = pd_first_cpu_reg; - _last_reg = pd_last_cpu_reg; + _last_reg = pd_last_cpu_reg - FrameMap::cpu_reg_range_reduction(); } assert(0 <= _first_reg && _first_reg < LinearScan::nof_regs, "out of range"); --- old/src/share/vm/c1/c1_Runtime1.cpp 2010-11-18 19:20:51.401332000 -0800 +++ new/src/share/vm/c1/c1_Runtime1.cpp 2010-11-18 19:20:51.199008000 -0800 @@ -1177,10 +1177,11 @@ assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); if (UseCompressedOops) { bs->write_ref_array_pre((narrowOop*)dst, num); + Copy::conjoint_oops_atomic((narrowOop*) src, (narrowOop*) dst, num); } else { bs->write_ref_array_pre((oop*)dst, num); + Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); } - Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); bs->write_ref_array(dst, num); JRT_END --- old/src/share/vm/code/relocInfo.cpp 2010-11-18 19:20:52.182528000 -0800 +++ new/src/share/vm/code/relocInfo.cpp 2010-11-18 19:20:51.983382000 -0800 @@ -1076,8 +1076,8 @@ tty->print_cr("(no relocs)"); return; } - tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT, - _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr); + tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d", + _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset()); if (current()->format() != 0) tty->print(" format=%d", current()->format()); if (datalen() == 1) { --- old/src/share/vm/runtime/arguments.cpp 2010-11-18 19:20:52.966074000 -0800 +++ new/src/share/vm/runtime/arguments.cpp 2010-11-18 19:20:52.754560000 -0800 @@ -960,24 +960,9 @@ void Arguments::check_compressed_oops_compat() { #ifdef _LP64 assert(UseCompressedOops, "Precondition"); -# if defined(COMPILER1) && !defined(TIERED) - // Until c1 supports compressed oops turn them off. - FLAG_SET_DEFAULT(UseCompressedOops, false); -# else // Is it on by default or set on ergonomically bool is_on_by_default = FLAG_IS_DEFAULT(UseCompressedOops) || FLAG_IS_ERGO(UseCompressedOops); - // Tiered currently doesn't work with compressed oops - if (TieredCompilation) { - if (is_on_by_default) { - FLAG_SET_DEFAULT(UseCompressedOops, false); - return; - } else { - vm_exit_during_initialization( - "Tiered compilation is not supported with compressed oops yet", NULL); - } - } - // If dumping an archive or forcing its use, disable compressed oops if possible if (DumpSharedSpaces || RequireSharedSpaces) { if (is_on_by_default) { @@ -991,8 +976,6 @@ // UseSharedSpaces is on by default. With compressed oops, we turn it off. FLAG_SET_DEFAULT(UseSharedSpaces, false); } - -# endif // defined(COMPILER1) && !defined(TIERED) #endif // _LP64 }