--- 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.