6985015: C1 needs to support compressed oops
authoriveresov
Tue, 30 Nov 2010 23:23:40 -0800
changeset 7427 d7b79a367474
parent 7397 5b173b4ca846
child 7428 d8b07f84ab7b
6985015: C1 needs to support compressed oops Summary: This change implements compressed oops for C1 for x64 and sparc. The changes are mostly on the codegen level, with a few exceptions when we do access things outside of the heap that are uncompressed from the IR. Compressed oops are now also enabled with tiered. Reviewed-by: twisti, kvn, never, phh
hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp
hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp
hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
hotspot/src/cpu/x86/vm/assembler_x86.hpp
hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp
hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp
hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp
hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp
hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
hotspot/src/share/vm/c1/c1_FrameMap.hpp
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
hotspot/src/share/vm/c1/c1_Instruction.hpp
hotspot/src/share/vm/c1/c1_LIR.cpp
hotspot/src/share/vm/c1/c1_LIR.hpp
hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
hotspot/src/share/vm/c1/c1_LIRAssembler.hpp
hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
hotspot/src/share/vm/c1/c1_LinearScan.cpp
hotspot/src/share/vm/c1/c1_Runtime1.cpp
hotspot/src/share/vm/code/relocInfo.cpp
hotspot/src/share/vm/runtime/arguments.cpp
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -909,10 +909,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
+    srl(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
+    srl(G4, 0,G4);              // Clear current high G4 bits
     or3 (G4,G2,G4);             // Recover 64-bit G4
 #endif
     restore(O0, 0, G2_thread);
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1798,6 +1798,7 @@
   // branches that use right instruction for v8 vs. v9
   inline void br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
   inline void br( Condition c, bool a, Predict p, Label& L );
+
   inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
   inline void fb( Condition c, bool a, Predict p, Label& L );
 
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -434,7 +434,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 /*wide*/, false /*unaligned*/);
   if (__ is_in_wdisp16_range(_continuation)) {
     __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
                       pre_val_reg, _continuation);
--- a/hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -155,4 +155,7 @@
   static bool is_caller_save_register (LIR_Opr  reg);
   static bool is_caller_save_register (Register r);
 
+  static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; }
+  static int last_cpu_reg()             { return pd_last_cpu_reg;  }
+
 #endif // CPU_SPARC_VM_C1_FRAMEMAP_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -100,6 +100,11 @@
         return false;
       }
 
+      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;
+      }
+
       if (dst->is_register()) {
         if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) {
           return !PatchALot;
@@ -253,7 +258,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);
@@ -262,7 +267,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);
@@ -766,7 +771,7 @@
 
 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);
+  __ load_klass(O0, G3_scratch);
   if (__ is_simm13(op->vtable_offset())) {
     __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method);
   } else {
@@ -780,138 +785,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
@@ -934,9 +818,22 @@
         __ 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:
+        {
+          if (UseCompressedOops && !wide) {
+            __ encode_heap_oop(from_reg->as_register(), G3_scratch);
+            store_offset = code_offset();
+            __ stw(G3_scratch, base, offset);
+          } else {
+            __ 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:
         {
@@ -958,8 +855,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
@@ -975,9 +874,21 @@
       __ 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:
+      {
+        if (UseCompressedOops && !wide) {
+          __ encode_heap_oop(from_reg->as_register(), G3_scratch);
+          store_offset = code_offset();
+          __ stw(G3_scratch, base, disp);
+        } else {
+          __ 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();
@@ -986,14 +897,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) {
@@ -1030,9 +941,18 @@
 #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:
+        {
+          if (UseCompressedOops && !wide) {
+            __ lduw(base, offset, to_reg->as_register());
+            __ decode_heap_oop(to_reg->as_register());
+          } else {
+            __ 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:
         {
@@ -1048,23 +968,34 @@
         }
       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:
+      {
+          if (UseCompressedOops && !wide) {
+            __ lduw(base, disp, to_reg->as_register());
+            __ decode_heap_oop(to_reg->as_register());
+          } else {
+            __ 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  :
@@ -1078,60 +1009,28 @@
       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_FLOAT: {
+      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());
+      __ stw(src_reg, addr.base(), addr.disp());
+      break;
+    }
     case T_ADDRESS: {
       Register src_reg = O7;
       int value = c->as_jint_bits();
@@ -1141,7 +1040,7 @@
         __ set(value, O7);
       }
       Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
-      __ stw(src_reg, addr.base(), addr.disp());
+      __ st_ptr(src_reg, addr.base(), addr.disp());
       break;
     }
     case T_OBJECT: {
@@ -1178,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();
-
-  if (info != NULL) {
-    add_debug_info_for_null_check_here(info);
-  }
+  int offset = -1;
+
   switch (c->type()) {
     case T_INT:
     case T_FLOAT:
@@ -1199,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;
     }
@@ -1212,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: {
@@ -1241,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;
@@ -1252,6 +1149,10 @@
     default:
       Unimplemented();
   }
+  if (info != NULL) {
+    assert(offset != -1, "offset should've been set");
+    add_debug_info_for_null_check(offset, info);
+  }
 }
 
 
@@ -1336,7 +1237,7 @@
           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());
         }
       }
       break;
@@ -1429,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 wide, bool unaligned) {
 
   LIR_Address* addr = src_opr->as_address_ptr();
   LIR_Opr to_reg = dest;
@@ -1475,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);
 }
 
@@ -1518,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);
 }
 
 
@@ -1530,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);
 }
 
 
@@ -1578,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 wide, bool unaligned) {
   LIR_Address* addr = dest->as_address_ptr();
 
   Register src = addr->base()->as_pointer_register();
@@ -1622,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) {
@@ -2184,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();
   }
 
@@ -2232,10 +2132,18 @@
   }
 
   if (flags & LIR_OpArrayCopy::type_check) {
-    __ 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());
+    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);
+      __ cmp(tmp, tmp2);
+      __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    } else {
+      __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
+      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      __ cmp(tmp, tmp2);
+      __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    }
     __ delayed()->nop();
   }
 
@@ -2250,20 +2158,44 @@
     // 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);
-    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);
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->nop();
+    if (UseCompressedOops) {
+      // tmp holds the default type. It currently comes uncompressed after the
+      // load of a constant, so encode it.
+      __ encode_heap_oop(tmp);
+      // load the raw value of the dst klass, since we will be comparing
+      // uncompressed values directly.
+      __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      if (basic_type != T_OBJECT) {
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::notEqual, false, Assembler::pn, halt);
+        // load the raw value of the src klass.
+        __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      } else {
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->cmp(src, dst);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      }
     } else {
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->cmp(src, dst);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->nop();
+      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      if (basic_type != T_OBJECT) {
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::notEqual, false, Assembler::pn, halt);
+        __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      } else {
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->cmp(src, dst);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      }
     }
     __ bind(halt);
     __ stop("incorrect type information in arraycopy");
@@ -2471,7 +2403,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);
@@ -2563,7 +2495,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);
@@ -2605,7 +2537,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);
@@ -2674,11 +2606,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);
 
@@ -2700,7 +2633,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();
@@ -2781,14 +2714,17 @@
     Register t2 = op->tmp2()->as_register();
     __ mov(cmp_value, t1);
     __ mov(new_value, t2);
-#ifdef _LP64
     if (op->code() == lir_cas_obj) {
-      __ casx(addr, t1, t2);
-    } else
-#endif
-      {
+      if (UseCompressedOops) {
+        __ encode_heap_oop(t1);
+        __ encode_heap_oop(t2);
         __ cas(addr, t1, t2);
+      } else {
+        __ casx(addr, t1, t2);
       }
+    } else {
+      __ cas(addr, t1, t2);
+    }
     __ cmp(t1, t2);
   } else {
     Unimplemented();
@@ -2966,7 +2902,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.
@@ -3160,7 +3096,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);
   }
 }
 
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -40,33 +40,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
-
-  // 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);
+  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);
 
-  // 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);
 
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -40,7 +40,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();
@@ -185,9 +185,19 @@
   } 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());
+  if (UseCompressedOops) {
+    // Save klass
+    mov(klass, t1);
+    encode_heap_oop_not_null(t1);
+    stw(t1, obj, oopDesc::klass_offset_in_bytes());
+  } else {
+    st_ptr(klass, obj, oopDesc::klass_offset_in_bytes());
+  }
+  if (len->is_valid()) st(len, obj, arrayOopDesc::length_offset_in_bytes());
+  else if (UseCompressedOops) {
+    store_klass_gap(G0, obj);
+  }
 }
 
 
@@ -235,7 +245,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);
 
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -612,7 +612,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);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -135,6 +135,7 @@
 // Using noreg ensures if the dead code is incorrectly live and executed it
 // will cause an assertion failure
 #define rscratch1 noreg
+#define rscratch2 noreg
 
 #endif // _LP64
 
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -483,7 +483,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 /*wide*/, false /*unaligned*/);
 
   __ cmpptr(pre_val_reg, (int32_t) NULL_WORD);
   __ jcc(Assembler::equal, _continuation);
--- a/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -61,8 +61,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,
--- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -158,9 +158,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);
@@ -191,9 +193,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
 
 
--- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -130,4 +130,15 @@
     return _caller_save_xmm_regs[i];
   }
 
+  static int adjust_reg_range(int range) {
+    // Reduce the number of available regs (to free r12) in case of compressed oops
+    if (UseCompressedOops) return range - 1;
+    return range;
+  }
+
+  static int nof_caller_save_cpu_regs() { return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map); }
+  static int last_cpu_reg()             { return adjust_reg_range(pd_last_cpu_reg);  }
+  static int last_byte_reg()            { return adjust_reg_range(pd_last_byte_reg); }
+
 #endif // CPU_X86_VM_C1_FRAMEMAP_X86_HPP
+
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -343,8 +343,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();
@@ -352,8 +352,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);
@@ -559,16 +559,16 @@
   __ movptr (rax, arg1->as_register());
 
   // Get addresses of first characters from both Strings
-  __ movptr (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)));
+  __ 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()));
-  __ 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)));
+  __ 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)));
 
   // compute minimum length (in rax) and difference of lengths (on top of stack)
   if (VM_Version::supports_cmov()) {
@@ -696,10 +696,15 @@
   LIR_Const* c = src->as_constant_ptr();
 
   switch (c->type()) {
-    case T_INT:
+    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");
-      __ movl(dest->as_register(), c->as_jint());
+      __ movptr(dest->as_register(), c->as_jint());
       break;
     }
 
@@ -780,8 +785,11 @@
   switch (c->type()) {
     case T_INT:  // fall through
     case T_FLOAT:
+      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
+      break;
+
     case T_ADDRESS:
-      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
+      __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
       break;
 
     case T_OBJECT:
@@ -806,7 +814,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();
@@ -816,14 +824,21 @@
   switch (type) {
     case T_INT:    // fall through
     case T_FLOAT:
+      __ movl(as_Address(addr), c->as_jint_bits());
+      break;
+
     case T_ADDRESS:
-      __ movl(as_Address(addr), c->as_jint_bits());
+      __ movptr(as_Address(addr), c->as_jint_bits());
       break;
 
     case T_OBJECT:  // fall through
     case T_ARRAY:
       if (c->as_jobject() == NULL) {
-        __ movptr(as_Address(addr), NULL_WORD);
+        if (UseCompressedOops && !wide) {
+          __ movl(as_Address(addr), (int32_t)NULL_WORD);
+        } else {
+          __ movptr(as_Address(addr), NULL_WORD);
+        }
       } else {
         if (is_literal_address(addr)) {
           ShouldNotReachHere();
@@ -831,8 +846,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
@@ -1009,22 +1030,28 @@
 }
 
 
-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 wide, bool /* unaligned */) {
   LIR_Address* to_addr = dest->as_address_ptr();
   PatchingStub* patch = NULL;
+  Register compressed_src = rscratch1;
 
   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()) {
@@ -1050,13 +1077,17 @@
       break;
     }
 
-    case T_ADDRESS: // fall through
     case T_ARRAY:   // fall through
     case T_OBJECT:  // fall through
-#ifdef _LP64
+      if (UseCompressedOops && !wide) {
+        __ movl(as_Address(to_addr), compressed_src);
+      } else {
+        __ movptr(as_Address(to_addr), src->as_register());
+      }
+      break;
+    case T_ADDRESS:
       __ movptr(as_Address(to_addr), src->as_register());
       break;
-#endif // _LP64
     case T_INT:
       __ movl(as_Address(to_addr), src->as_register());
       break;
@@ -1113,6 +1144,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);
@@ -1196,7 +1230,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 wide, bool /* unaligned */) {
   assert(src->is_address(), "should not call otherwise");
   assert(dest->is_register(), "should not call otherwise");
 
@@ -1250,13 +1284,18 @@
       break;
     }
 
-    case T_ADDRESS: // fall through
     case T_OBJECT:  // fall through
     case T_ARRAY:   // fall through
-#ifdef _LP64
+      if (UseCompressedOops && !wide) {
+        __ movl(dest->as_register(), from_addr);
+      } else {
+        __ movptr(dest->as_register(), from_addr);
+      }
+      break;
+
+    case T_ADDRESS:
       __ movptr(dest->as_register(), from_addr);
       break;
-#endif // _L64
     case T_INT:
       __ movl(dest->as_register(), from_addr);
       break;
@@ -1351,6 +1390,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());
   }
 }
@@ -1690,7 +1734,7 @@
   } else if (obj == klass_RInfo) {
     klass_RInfo = dst;
   }
-  if (k->is_loaded()) {
+  if (k->is_loaded() && !UseCompressedOops) {
     select_different_registers(obj, dst, k_RInfo, klass_RInfo);
   } else {
     Rtmp1 = op->tmp3()->as_register();
@@ -1727,21 +1771,26 @@
   if (op->fast_check()) {
     // get object class
     // not a safepoint as obj null check happens earlier
-    if (k->is_loaded()) {
 #ifdef _LP64
-      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
-#else
-      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
-#endif // _LP64
+    if (UseCompressedOops) {
+      __ load_klass(Rtmp1, obj);
+      __ cmpptr(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());
+    } 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
@@ -1796,7 +1845,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);
@@ -1860,10 +1909,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()));
-
-    // get instance klass
+    __ load_klass(k_RInfo, array);
+    __ load_klass(klass_RInfo, value);
+
+    // 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);
@@ -1882,7 +1931,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);
@@ -1946,12 +1995,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
@@ -3193,8 +3262,13 @@
   }
 
   if (flags & LIR_OpArrayCopy::type_check) {
-    __ movptr(tmp, src_klass_addr);
-    __ cmpptr(tmp, dst_klass_addr);
+    if (UseCompressedOops) {
+      __ movl(tmp, src_klass_addr);
+      __ cmpl(tmp, dst_klass_addr);
+    } else {
+      __ movptr(tmp, src_klass_addr);
+      __ cmpptr(tmp, dst_klass_addr);
+    }
     __ jcc(Assembler::notEqual, *stub->entry());
   }
 
@@ -3209,13 +3283,23 @@
     // 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);
+
+      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
+      else                   __ cmpptr(tmp, dst_klass_addr);
       __ jcc(Assembler::notEqual, halt);
-      __ cmpptr(tmp, src_klass_addr);
+      if (UseCompressedOops) __ cmpl(tmp, src_klass_addr);
+      else                   __ cmpptr(tmp, src_klass_addr);
       __ jcc(Assembler::equal, known_ok);
     } else {
-      __ cmpptr(tmp, dst_klass_addr);
+      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
+      else                   __ cmpptr(tmp, dst_klass_addr);
       __ jcc(Assembler::equal, known_ok);
       __ cmpptr(src, dst);
       __ jcc(Assembler::equal, known_ok);
@@ -3344,7 +3428,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.
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1151,9 +1151,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() || UseCompressedOops) {
+    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());
 }
@@ -1170,9 +1173,12 @@
     patching_info = state_for(x, x->state_before());
   }
   obj.load_item();
+  LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
+  if (!x->klass()->is_loaded() || UseCompressedOops) {
+    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());
 }
 
--- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -31,18 +31,17 @@
   assert(FrameMap::rsp_opr->cpu_regnr() == 6, "wrong assumption below");
   assert(FrameMap::rbp_opr->cpu_regnr() == 7, "wrong assumption below");
   assert(reg_num >= 0, "invalid reg_num");
-
-  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;
 #endif // _LP64
+  return reg_num <= FrameMap::last_cpu_reg() || reg_num >= pd_nof_cpu_regs_frame_map;
 }
 
 inline int LinearScan::num_physical_regs(BasicType type) {
@@ -104,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 = FrameMap::last_byte_reg();
     return true;
   } else if ((UseSSE >= 1 && cur->type() == T_FLOAT) || (UseSSE >= 2 && cur->type() == T_DOUBLE)) {
     _first_reg = pd_first_xmm_reg;
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -155,11 +155,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
 }
 
 
@@ -230,7 +245,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);
 
@@ -317,13 +332,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()));
+
+  if (UseCompressedOops) {
+    load_klass(rscratch1, receiver);
+    cmpptr(rscratch1, iCache);
+  } else {
+    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");
 }
 
 
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1261,7 +1261,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);
--- a/hotspot/src/share/vm/c1/c1_FrameMap.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -76,8 +76,8 @@
     nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc,
     nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc,
 
-    nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map,
-    nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map,
+    max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map,
+    nof_caller_save_fpu_regs     = pd_nof_caller_save_fpu_regs_frame_map,
 
     spill_slot_size_in_bytes = 4
   };
@@ -97,7 +97,7 @@
   static Register     _cpu_rnr2reg [nof_cpu_regs];
   static int          _cpu_reg2rnr [nof_cpu_regs];
 
-  static LIR_Opr      _caller_save_cpu_regs [nof_caller_save_cpu_regs];
+  static LIR_Opr      _caller_save_cpu_regs [max_nof_caller_save_cpu_regs];
   static LIR_Opr      _caller_save_fpu_regs [nof_caller_save_fpu_regs];
 
   int                 _framesize;
@@ -243,7 +243,7 @@
   VMReg regname(LIR_Opr opr) const;
 
   static LIR_Opr caller_save_cpu_reg_at(int i) {
-    assert(i >= 0 && i < nof_caller_save_cpu_regs, "out of bounds");
+    assert(i >= 0 && i < max_nof_caller_save_cpu_regs, "out of bounds");
     return _caller_save_cpu_regs[i];
   }
 
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -2795,7 +2795,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);
   }
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -2110,20 +2110,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; }
 };
 
 
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1742,6 +1742,8 @@
       return "unaligned move";
     case lir_move_volatile:
       return "volatile_move";
+    case lir_move_wide:
+      return "wide_move";
     default:
       ShouldNotReachHere();
     return "illegal_op";
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -985,6 +985,7 @@
   lir_move_normal,
   lir_move_volatile,
   lir_move_unaligned,
+  lir_move_wide,
   lir_move_max_flag
 };
 
@@ -1932,7 +1933,20 @@
   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) {
+    if (UseCompressedOops) {
+      append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info, lir_move_wide));
+    } else {
+      move(src, dst, info);
+    }
+  }
+  void move_wide(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) {
+    if (UseCompressedOops) {
+      append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info, lir_move_wide));
+    } else {
+      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));   }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -489,7 +489,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;
 
@@ -758,7 +760,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");
@@ -767,7 +769,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, wide, unaligned);
     } else {
       ShouldNotReachHere();
     }
@@ -790,13 +792,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, wide, unaligned);
 
   } else {
     ShouldNotReachHere();
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Tue Nov 30 23:23:40 2010 -0800
@@ -165,15 +165,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 wide, bool unaligned);
   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 wide, bool unaligned);
 
   void prefetchr  (LIR_Opr src);
   void prefetchw  (LIR_Opr src);
@@ -211,7 +213,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);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -864,11 +864,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);
   }
 }
 
@@ -1009,12 +1009,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);
@@ -1085,7 +1085,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());
@@ -1122,8 +1122,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);
 }
 
 
@@ -1131,7 +1131,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);
 }
 
 
@@ -1908,7 +1908,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);
+    }
   }
 }
 
@@ -2287,7 +2291,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());
@@ -2352,11 +2356,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);
+        }
     }
   }
 
@@ -2368,7 +2375,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());
     }
   }
 }
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1273,7 +1273,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(); 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");
@@ -3557,7 +3557,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(); 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++) {
@@ -5596,7 +5596,7 @@
     _last_reg = pd_last_fpu_reg;
   } else {
     _first_reg = pd_first_cpu_reg;
-    _last_reg = pd_last_cpu_reg;
+    _last_reg = FrameMap::last_cpu_reg();
   }
 
   assert(0 <= _first_reg && _first_reg < LinearScan::nof_regs, "out of range");
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1174,7 +1174,7 @@
     memmove(dst_addr, src_addr, length << l2es);
     return ac_ok;
   } else if (src->is_objArray() && dst->is_objArray()) {
-    if (UseCompressedOops) {  // will need for tiered
+    if (UseCompressedOops) {
       narrowOop *src_addr  = objArrayOop(src)->obj_at_addr<narrowOop>(src_pos);
       narrowOop *dst_addr  = objArrayOop(dst)->obj_at_addr<narrowOop>(dst_pos);
       return obj_arraycopy_work(src, src_addr, dst, dst_addr, length);
@@ -1210,10 +1210,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
 
--- a/hotspot/src/share/vm/code/relocInfo.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/code/relocInfo.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1093,8 +1093,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) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -1007,24 +1007,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) {
@@ -1038,9 +1023,7 @@
     // UseSharedSpaces is on by default. With compressed oops, we turn it off.
     FLAG_SET_DEFAULT(UseSharedSpaces, false);
   }
-
-#  endif // defined(COMPILER1) && !defined(TIERED)
-#endif // _LP64
+#endif
 }
 
 void Arguments::set_tiered_flags() {
@@ -3075,11 +3058,9 @@
   // Set flags based on ergonomics.
   set_ergonomics_flags();
 
-#ifdef _LP64
   if (UseCompressedOops) {
     check_compressed_oops_compat();
   }
-#endif
 
   // Check the GC selections again.
   if (!check_gc_consistency()) {