changeset 1797:beba40b26a79

Merge
author acorn
date Fri, 15 Oct 2010 15:12:04 -0400
parents 75b0735b4d04 ee813f7b46e4
children 75ab0162aa84
files src/cpu/x86/vm/methodHandles_x86.cpp
diffstat 41 files changed, 615 insertions(+), 493 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -3094,11 +3094,10 @@
 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
                                               Register temp_reg,
                                               Label& wrong_method_type) {
-  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
   assert_different_registers(mtype_reg, mh_reg, temp_reg);
   // compare method type against that of the receiver
   RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg);
-  ld_ptr(mh_reg, mhtype_offset, temp_reg);
+  load_heap_oop(mh_reg, mhtype_offset, temp_reg);
   cmp(temp_reg, mtype_reg);
   br(Assembler::notEqual, false, Assembler::pn, wrong_method_type);
   delayed()->nop();
@@ -3112,16 +3111,15 @@
 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
                                                 Register temp_reg) {
   assert_different_registers(vmslots_reg, mh_reg, temp_reg);
-  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
   // load mh.type.form.vmslots
   if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
     // hoist vmslots into every mh to avoid dependent load chain
-    ld(    Address(mh_reg,    delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
+    ld(           Address(mh_reg,    delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
   } else {
     Register temp2_reg = vmslots_reg;
-    ld_ptr(Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
-    ld_ptr(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
-    ld(    Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
+    load_heap_oop(Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
+    load_heap_oop(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
+    ld(           Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
   }
 }
 
@@ -3130,9 +3128,8 @@
   assert(mh_reg == G3_method_handle, "caller must put MH object in G3");
   assert_different_registers(mh_reg, temp_reg);
 
-  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
-
   // pick out the interpreted side of the handler
+  // NOTE: vmentry is not an oop!
   ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
 
   // off we go...
@@ -4653,6 +4650,11 @@
   }
 }
 
+void MacroAssembler::load_heap_oop(Register s1, RegisterOrConstant s2, Register d) {
+  if (s2.is_constant())  load_heap_oop(s1, s2.as_constant(), d);
+  else                   load_heap_oop(s1, s2.as_register(), d);
+}
+
 void MacroAssembler::store_heap_oop(Register d, Register s1, Register s2) {
   if (UseCompressedOops) {
     assert(s1 != d && s2 != d, "not enough registers");
--- a/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -825,6 +825,12 @@
   // test if -4096 <= x <= 4095
   static bool is_simm13(int x) { return is_simm(x, 13); }
 
+  // test if label is in simm16 range in words (wdisp16).
+  bool is_in_wdisp16_range(Label& L) {
+    intptr_t d = intptr_t(pc()) - intptr_t(target(L));
+    return is_simm(d, 18);
+  }
+
   enum ASIs { // page 72, v9
     ASI_PRIMARY        = 0x80,
     ASI_PRIMARY_LITTLE = 0x88
@@ -2103,6 +2109,7 @@
   void load_heap_oop(const Address& s, Register d);
   void load_heap_oop(Register s1, Register s2, Register d);
   void load_heap_oop(Register s1, int simm13a, Register d);
+  void load_heap_oop(Register s1, RegisterOrConstant s2, Register d);
   void store_heap_oop(Register d, Register s1, Register s2);
   void store_heap_oop(Register d, Register s1, int simm13a);
   void store_heap_oop(Register d, const Address& a, int offset = 0);
@@ -2225,7 +2232,7 @@
   void stop(const char* msg);                          // prints msg, dumps registers and stops execution
   void warn(const char* msg);                          // prints msg, but don't stop
   void untested(const char* what = "");
-  void unimplemented(const char* what = "")              { char* b = new char[1024];  sprintf(b, "unimplemented: %s", what);  stop(b); }
+  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, 1024, "unimplemented: %s", what);  stop(b); }
   void should_not_reach_here()                   { stop("should not reach here"); }
   void print_CPU_state();
 
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -425,8 +425,13 @@
   Register pre_val_reg = pre_val()->as_register();
 
   ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false);
-  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
-                    pre_val_reg, _continuation);
+  if (__ is_in_wdisp16_range(_continuation)) {
+    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
+                      pre_val_reg, _continuation);
+  } else {
+    __ cmp(pre_val_reg, G0);
+    __ brx(Assembler::equal, false, Assembler::pn, _continuation);
+  }
   __ delayed()->nop();
 
   __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
@@ -452,8 +457,13 @@
   assert(new_val()->is_register(), "Precondition.");
   Register addr_reg = addr()->as_pointer_register();
   Register new_val_reg = new_val()->as_register();
-  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
-                    new_val_reg, _continuation);
+  if (__ is_in_wdisp16_range(_continuation)) {
+    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
+                      new_val_reg, _continuation);
+  } else {
+    __ cmp(new_val_reg, G0);
+    __ brx(Assembler::equal, false, Assembler::pn, _continuation);
+  }
   __ delayed()->nop();
 
   __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id));
--- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -664,7 +664,7 @@
   // Use temps to avoid kills
   LIR_Opr t1 = FrameMap::G1_opr;
   LIR_Opr t2 = FrameMap::G3_opr;
-  LIR_Opr addr = new_pointer_register();
+  LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
 
   // get address of field
   obj.load_item();
--- a/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -64,7 +64,7 @@
     _first_reg = pd_first_callee_saved_reg;
     _last_reg = pd_last_callee_saved_reg;
     return true;
-  } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT) {
+  } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_ADDRESS) {
     _first_reg = pd_first_cpu_reg;
     _last_reg = pd_last_allocatable_cpu_reg;
     return true;
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -27,6 +27,14 @@
 
 #define __ _masm->
 
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
                                                 address interpreted_entry) {
   // Just before the actual machine code entry point, allocate space
@@ -90,8 +98,8 @@
   }
 
   // given the MethodType, find out where the MH argument is buried
-  __ ld_ptr(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)),        O0_argslot);
-  __ ldsw(  Address(O0_argslot,     __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot);
+  __ load_heap_oop(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)),        O0_argslot);
+  __ ldsw(         Address(O0_argslot,     __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot);
   __ ld_ptr(__ argument_address(O0_argslot), G3_method_handle);
 
   __ check_method_handle_type(G5_method_type, G3_method_handle, O1_scratch, wrong_method_type);
@@ -105,6 +113,7 @@
 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) {
   // Verify that argslot lies within (Gargs, FP].
   Label L_ok, L_bad;
+  BLOCK_COMMENT("{ verify_argslot");
 #ifdef _LP64
   __ add(FP, STACK_BIAS, temp_reg);
   __ cmp(argslot_reg, temp_reg);
@@ -119,6 +128,7 @@
   __ bind(L_bad);
   __ stop(error_message);
   __ bind(L_ok);
+  BLOCK_COMMENT("} verify_argslot");
 }
 #endif
 
@@ -175,6 +185,7 @@
   //   for (temp = sp + size; temp < argslot; temp++)
   //     temp[-size] = temp[0]
   //   argslot -= size;
+  BLOCK_COMMENT("insert_arg_slots {");
   RegisterOrConstant offset = __ regcon_sll_ptr(arg_slots, LogBytesPerWord, temp3_reg);
 
   // Keep the stack pointer 2*wordSize aligned.
@@ -187,7 +198,7 @@
 
   {
     Label loop;
-    __ bind(loop);
+    __ BIND(loop);
     // pull one word down each time through the loop
     __ ld_ptr(Address(temp_reg, 0), temp2_reg);
     __ st_ptr(temp2_reg, Address(temp_reg, offset));
@@ -199,6 +210,7 @@
 
   // Now move the argslot down, to point to the opened-up space.
   __ add(argslot_reg, offset, argslot_reg);
+  BLOCK_COMMENT("} insert_arg_slots");
 }
 
 
@@ -235,6 +247,7 @@
   }
 #endif // ASSERT
 
+  BLOCK_COMMENT("remove_arg_slots {");
   // Pull up everything shallower than argslot.
   // Then remove the excess space on the stack.
   // The stacked return address gets pulled up with everything else.
@@ -246,7 +259,7 @@
   __ sub(argslot_reg, wordSize, temp_reg);  // source pointer for copy
   {
     Label loop;
-    __ bind(loop);
+    __ BIND(loop);
     // pull one word up each time through the loop
     __ ld_ptr(Address(temp_reg, 0), temp2_reg);
     __ st_ptr(temp2_reg, Address(temp_reg, offset));
@@ -265,29 +278,35 @@
   const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1);
   RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg);
   __ add(SP, masked_offset, SP);
+  BLOCK_COMMENT("} remove_arg_slots");
 }
 
 
 #ifndef PRODUCT
 extern "C" void print_method_handle(oop mh);
 void trace_method_handle_stub(const char* adaptername,
-                              oop mh) {
-#if 0
-                              intptr_t* entry_sp,
-                              intptr_t* saved_sp,
-                              intptr_t* saved_bp) {
-  // called as a leaf from native code: do not block the JVM!
-  intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
-  intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
-  printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
-         adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
-  if (last_sp != saved_sp)
-    printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
-#endif
-
+                              oopDesc* mh) {
   printf("MH %s mh="INTPTR_FORMAT"\n", adaptername, (intptr_t) mh);
   print_method_handle(mh);
 }
+void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
+  if (!TraceMethodHandles)  return;
+  BLOCK_COMMENT("trace_method_handle {");
+  // save: Gargs, O5_savedSP
+  __ save_frame(16);
+  __ set((intptr_t) adaptername, O0);
+  __ mov(G3_method_handle, O1);
+  __ mov(G3_method_handle, L3);
+  __ mov(Gargs, L4);
+  __ mov(G5_method_type, L5);
+  __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
+
+  __ mov(L3, G3_method_handle);
+  __ mov(L4, Gargs);
+  __ mov(L5, G5_method_type);
+  __ restore();
+  BLOCK_COMMENT("} trace_method_handle");
+}
 #endif // PRODUCT
 
 // which conversion op types are implemented here?
@@ -348,18 +367,8 @@
   }
 
   address interp_entry = __ pc();
-  if (UseCompressedOops)  __ unimplemented("UseCompressedOops");
 
-#ifndef PRODUCT
-  if (TraceMethodHandles) {
-    // save: Gargs, O5_savedSP
-    __ save(SP, -16*wordSize, SP);
-    __ set((intptr_t) entry_name(ek), O0);
-    __ mov(G3_method_handle, O1);
-    __ call_VM_leaf(Lscratch, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
-    __ restore(SP, 16*wordSize, SP);
-  }
-#endif // PRODUCT
+  trace_method_handle(_masm, entry_name(ek));
 
   switch ((int) ek) {
   case _raise_exception:
@@ -413,7 +422,7 @@
   case _invokestatic_mh:
   case _invokespecial_mh:
     {
-      __ ld_ptr(G3_mh_vmtarget, G5_method);  // target is a methodOop
+      __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
       __ verify_oop(G5_method);
       // Same as TemplateTable::invokestatic or invokespecial,
       // minus the CP setup and profiling:
@@ -468,7 +477,7 @@
       // minus the CP setup and profiling:
       __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
       Register O1_intf  = O1_scratch;
-      __ ld_ptr(G3_mh_vmtarget, O1_intf);
+      __ load_heap_oop(G3_mh_vmtarget, O1_intf);
       __ ldsw(G3_dmh_vmindex, G5_index);
       __ ld_ptr(__ argument_address(O0_argslot, -1), G3_method_handle);
       __ null_check(G3_method_handle, oopDesc::klass_offset_in_bytes());
@@ -523,7 +532,7 @@
       insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, O0_argslot, O1_scratch, O2_scratch, G5_index);
 
       // Store bound argument into the new stack slot:
-      __ ld_ptr(G3_bmh_argument, O1_scratch);
+      __ load_heap_oop(G3_bmh_argument, O1_scratch);
       if (arg_type == T_OBJECT) {
         __ st_ptr(O1_scratch, Address(O0_argslot, 0));
       } else {
@@ -541,12 +550,12 @@
       }
 
       if (direct_to_method) {
-        __ ld_ptr(G3_mh_vmtarget, G5_method);  // target is a methodOop
+        __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
         __ verify_oop(G5_method);
         __ jump_indirect_to(G5_method_fie, O1_scratch);
         __ delayed()->nop();
       } else {
-        __ ld_ptr(G3_mh_vmtarget, G3_method_handle);  // target is a methodOop
+        __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);  // target is a methodOop
         __ verify_oop(G3_method_handle);
         __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
       }
@@ -556,7 +565,7 @@
   case _adapter_retype_only:
   case _adapter_retype_raw:
     // Immediately jump to the next MH layer:
-    __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+    __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
     __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     // This is OK when all parameter types widen.
     // It is also OK when a return type narrows.
@@ -572,8 +581,8 @@
       Address vmarg = __ argument_address(O0_argslot);
 
       // What class are we casting to?
-      __ ld_ptr(G3_amh_argument, G5_klass);  // This is a Class object!
-      __ ld_ptr(Address(G5_klass, java_lang_Class::klass_offset_in_bytes()), G5_klass);
+      __ load_heap_oop(G3_amh_argument, G5_klass);  // This is a Class object!
+      __ load_heap_oop(Address(G5_klass, java_lang_Class::klass_offset_in_bytes()), G5_klass);
 
       Label done;
       __ ld_ptr(vmarg, O1_scratch);
@@ -590,14 +599,14 @@
 
       // If we get here, the type check failed!
       __ ldsw(G3_amh_vmargslot, O0_argslot);  // reload argslot field
-      __ ld_ptr(G3_amh_argument, O3_scratch);  // required class
+      __ load_heap_oop(G3_amh_argument, O3_scratch);  // required class
       __ ld_ptr(vmarg, O2_scratch);  // bad object
       __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
       __ delayed()->mov(Bytecodes::_checkcast, O1_scratch);  // who is complaining?
 
       __ bind(done);
       // Get the new MH:
-      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
       __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     }
     break;
@@ -676,7 +685,7 @@
       __ st(O1_scratch, vmarg);
 
       // Get the new MH:
-      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
       __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     }
     break;
@@ -721,7 +730,7 @@
         ShouldNotReachHere();
       }
 
-      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
       __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     }
     break;
@@ -851,7 +860,7 @@
         }
       }
 
-      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
       __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     }
     break;
@@ -895,7 +904,7 @@
       __ brx(Assembler::less, false, Assembler::pt, loop);
       __ delayed()->nop();  // FILLME
 
-      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
       __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     }
     break;
@@ -913,7 +922,7 @@
 
       remove_arg_slots(_masm, G5_stack_move, O0_argslot, O1_scratch, O2_scratch, O3_scratch);
 
-      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
+      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
       __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
     }
     break;
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -2586,6 +2586,8 @@
     __ restore();
 #endif
 
+    assert_clean_int(O2_count, G1);     // Make sure 'count' is clean int.
+
 #ifdef ASSERT
     // caller guarantees that the arrays really are different
     // otherwise, we would have to make conjoint checks
@@ -2600,8 +2602,6 @@
     }
 #endif //ASSERT
 
-    assert_clean_int(O2_count, G1);     // Make sure 'count' is clean int.
-
     checkcast_copy_entry = __ pc();
     // caller can pass a 64-bit byte count here (from generic stub)
     BLOCK_COMMENT("Entry:");
--- a/src/cpu/sparc/vm/stubRoutines_sparc.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/stubRoutines_sparc.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -43,7 +43,7 @@
 
 // MethodHandles adapters
 enum method_handles_platform_dependent_constants {
-  method_handles_adapters_code_size = 12000
+  method_handles_adapters_code_size = 15000
 };
 
 class Sparc {
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -3273,7 +3273,7 @@
   __ sll(Rret, LogBytesPerWord, Rret);
   __ ld_ptr(Rtemp, Rret, Rret);  // get return address
 
-  __ ld_ptr(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
+  __ load_heap_oop(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
   __ null_check(G3_method_handle);
 
   // Adjust Rret first so Llast_SP can be same as Rret
--- a/src/cpu/x86/vm/assembler_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -7709,9 +7709,14 @@
 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
                                               Register temp_reg,
                                               Label& wrong_method_type) {
-  if (UseCompressedOops)  unimplemented();  // field accesses must decode
+  Address type_addr(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg));
   // compare method type against that of the receiver
-  cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
+  if (UseCompressedOops) {
+    load_heap_oop(temp_reg, type_addr);
+    cmpptr(mtype_reg, temp_reg);
+  } else {
+    cmpptr(mtype_reg, type_addr);
+  }
   jcc(Assembler::notEqual, wrong_method_type);
 }
 
@@ -7723,15 +7728,14 @@
 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
                                                 Register temp_reg) {
   assert_different_registers(vmslots_reg, mh_reg, temp_reg);
-  if (UseCompressedOops)  unimplemented();  // field accesses must decode
   // load mh.type.form.vmslots
   if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
     // hoist vmslots into every mh to avoid dependent load chain
     movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
   } else {
     Register temp2_reg = vmslots_reg;
-    movptr(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
-    movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
+    load_heap_oop(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
+    load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
     movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
   }
 }
@@ -7745,9 +7749,8 @@
   assert(mh_reg == rcx, "caller must put MH object in rcx");
   assert_different_registers(mh_reg, temp_reg);
 
-  if (UseCompressedOops)  unimplemented();  // field accesses must decode
-
   // pick out the interpreted side of the handler
+  // NOTE: vmentry is not an oop!
   movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
 
   // off we go...
@@ -8238,6 +8241,40 @@
     movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src);
 }
 
+void MacroAssembler::load_heap_oop(Register dst, Address src) {
+#ifdef _LP64
+  if (UseCompressedOops) {
+    movl(dst, src);
+    decode_heap_oop(dst);
+  } else
+#endif
+    movptr(dst, src);
+}
+
+void MacroAssembler::store_heap_oop(Address dst, Register src) {
+#ifdef _LP64
+  if (UseCompressedOops) {
+    assert(!dst.uses(src), "not enough registers");
+    encode_heap_oop(src);
+    movl(dst, src);
+  } else
+#endif
+    movptr(dst, src);
+}
+
+// Used for storing NULLs.
+void MacroAssembler::store_heap_oop_null(Address dst) {
+#ifdef _LP64
+  if (UseCompressedOops) {
+    movl(dst, (int32_t)NULL_WORD);
+  } else {
+    movslq(dst, (int32_t)NULL_WORD);
+  }
+#else
+  movl(dst, (int32_t)NULL_WORD);
+#endif
+}
+
 #ifdef _LP64
 void MacroAssembler::store_klass_gap(Register dst, Register src) {
   if (UseCompressedOops) {
@@ -8246,34 +8283,6 @@
   }
 }
 
-void MacroAssembler::load_heap_oop(Register dst, Address src) {
-  if (UseCompressedOops) {
-    movl(dst, src);
-    decode_heap_oop(dst);
-  } else {
-    movq(dst, src);
-  }
-}
-
-void MacroAssembler::store_heap_oop(Address dst, Register src) {
-  if (UseCompressedOops) {
-    assert(!dst.uses(src), "not enough registers");
-    encode_heap_oop(src);
-    movl(dst, src);
-  } else {
-    movq(dst, src);
-  }
-}
-
-// Used for storing NULLs.
-void MacroAssembler::store_heap_oop_null(Address dst) {
-  if (UseCompressedOops) {
-    movl(dst, (int32_t)NULL_WORD);
-  } else {
-    movslq(dst, (int32_t)NULL_WORD);
-  }
-}
-
 #ifdef ASSERT
 void MacroAssembler::verify_heapbase(const char* msg) {
   assert (UseCompressedOops, "should be compressed");
--- a/src/cpu/x86/vm/assembler_x86.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1682,24 +1682,24 @@
   void load_klass(Register dst, Register src);
   void store_klass(Register dst, Register src);
 
+  void load_heap_oop(Register dst, Address src);
+  void store_heap_oop(Address dst, Register src);
+
+  // Used for storing NULL. All other oop constants should be
+  // stored using routines that take a jobject.
+  void store_heap_oop_null(Address dst);
+
   void load_prototype_header(Register dst, Register src);
 
 #ifdef _LP64
   void store_klass_gap(Register dst, Register src);
 
-  void load_heap_oop(Register dst, Address src);
-  void store_heap_oop(Address dst, Register src);
-
   // This dummy is to prevent a call to store_heap_oop from
   // converting a zero (like NULL) into a Register by giving
   // the compiler two choices it can't resolve
 
   void store_heap_oop(Address dst, void* dummy);
 
-  // Used for storing NULL. All other oop constants should be
-  // stored using routines that take a jobject.
-  void store_heap_oop_null(Address dst);
-
   void encode_heap_oop(Register r);
   void decode_heap_oop(Register r);
   void encode_heap_oop_not_null(Register r);
@@ -1927,7 +1927,7 @@
 
   void untested()                                { stop("untested"); }
 
-  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, sizeof(b), "unimplemented: %s", what);  stop(b); }
+  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, 1024, "unimplemented: %s", what);  stop(b); }
 
   void should_not_reach_here()                   { stop("should not reach here"); }
 
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1941,8 +1941,6 @@
       __ cmpxchgptr(newval, Address(addr, 0));
     } else if (op->code() == lir_cas_int) {
       __ cmpxchgl(newval, Address(addr, 0));
-    } else {
-      LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0)));
     }
 #ifdef _LP64
   } else if (op->code() == lir_cas_long) {
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -765,7 +765,7 @@
     ShouldNotReachHere();
   }
 
-  LIR_Opr addr = new_pointer_register();
+  LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
   LIR_Address* a;
   if(offset.result()->is_constant()) {
     a = new LIR_Address(obj.result(),
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -123,11 +123,9 @@
   }
 
   // given the MethodType, find out where the MH argument is buried
-  __ movptr(rdx_temp, Address(rax_mtype,
-                              __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
+  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
   Register rdx_vmslots = rdx_temp;
-  __ movl(rdx_vmslots, Address(rdx_temp,
-                               __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
+  __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
   __ movptr(rcx_recv, __ argument_address(rdx_vmslots));
 
   trace_method_handle(_masm, "invokeExact");
@@ -154,20 +152,18 @@
                    rcx_argslot, rbx_temp, rdx_temp);
 
   // load up an adapter from the calling type (Java weaves this)
-  __ movptr(rdx_temp, Address(rax_mtype,
-                              __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
+  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
   Register rdx_adapter = rdx_temp;
-  // movptr(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
+  // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
   // deal with old JDK versions:
-  __ lea(rdi_temp, Address(rdx_temp,
-                           __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
+  __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
   __ cmpptr(rdi_temp, rdx_temp);
   Label sorry_no_invoke_generic;
-  __ jccb(Assembler::below, sorry_no_invoke_generic);
+  __ jcc(Assembler::below, sorry_no_invoke_generic);
 
-  __ movptr(rdx_adapter, Address(rdi_temp, 0));
+  __ load_heap_oop(rdx_adapter, Address(rdi_temp, 0));
   __ testptr(rdx_adapter, rdx_adapter);
-  __ jccb(Assembler::zero, sorry_no_invoke_generic);
+  __ jcc(Assembler::zero, sorry_no_invoke_generic);
   __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter);
   // As a trusted first argument, pass the type being called, so the adapter knows
   // the actual types of the arguments and return values.
@@ -431,7 +427,6 @@
   }
 
   address interp_entry = __ pc();
-  if (UseCompressedOops)  __ unimplemented("UseCompressedOops");
 
   trace_method_handle(_masm, entry_name(ek));
 
@@ -489,7 +484,7 @@
   case _invokespecial_mh:
     {
       Register rbx_method = rbx_temp;
-      __ movptr(rbx_method, rcx_mh_vmtarget); // target is a methodOop
+      __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop
       __ verify_oop(rbx_method);
       // same as TemplateTable::invokestatic or invokespecial,
       // minus the CP setup and profiling:
@@ -546,8 +541,8 @@
       __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
       Register rdx_intf  = rdx_temp;
       Register rbx_index = rbx_temp;
-      __ movptr(rdx_intf,  rcx_mh_vmtarget);
-      __ movl(rbx_index,   rcx_dmh_vmindex);
+      __ load_heap_oop(rdx_intf, rcx_mh_vmtarget);
+      __ movl(rbx_index, rcx_dmh_vmindex);
       __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
       __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
 
@@ -602,7 +597,7 @@
                        rax_argslot, rbx_temp, rdx_temp);
 
       // store bound argument into the new stack slot:
-      __ movptr(rbx_temp, rcx_bmh_argument);
+      __ load_heap_oop(rbx_temp, rcx_bmh_argument);
       Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
       if (arg_type == T_OBJECT) {
         __ movptr(Address(rax_argslot, 0), rbx_temp);
@@ -620,11 +615,11 @@
 
       if (direct_to_method) {
         Register rbx_method = rbx_temp;
-        __ movptr(rbx_method, rcx_mh_vmtarget);
+        __ load_heap_oop(rbx_method, rcx_mh_vmtarget);
         __ verify_oop(rbx_method);
         __ jmp(rbx_method_fie);
       } else {
-        __ movptr(rcx_recv, rcx_mh_vmtarget);
+        __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
         __ verify_oop(rcx_recv);
         __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
       }
@@ -634,7 +629,7 @@
   case _adapter_retype_only:
   case _adapter_retype_raw:
     // immediately jump to the next MH layer:
-    __ movptr(rcx_recv, rcx_mh_vmtarget);
+    __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
     __ verify_oop(rcx_recv);
     __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     // This is OK when all parameter types widen.
@@ -651,13 +646,13 @@
       vmarg = __ argument_address(rax_argslot);
 
       // What class are we casting to?
-      __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
-      __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
+      __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
+      __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
 
       Label done;
       __ movptr(rdx_temp, vmarg);
       __ testptr(rdx_temp, rdx_temp);
-      __ jccb(Assembler::zero, done);         // no cast if null
+      __ jcc(Assembler::zero, done);         // no cast if null
       __ load_klass(rdx_temp, rdx_temp);
 
       // live at this point:
@@ -672,14 +667,15 @@
       __ movl(rax_argslot, rcx_amh_vmargslot);  // reload argslot field
       __ movptr(rdx_temp, vmarg);
 
-      __ pushptr(rcx_amh_argument); // required class
-      __ push(rdx_temp);            // bad object
-      __ push((int)Bytecodes::_checkcast);  // who is complaining?
+      __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class
+      __ push(rbx_klass);
+      __ push(rdx_temp);                             // bad object
+      __ push((int)Bytecodes::_checkcast);           // who is complaining?
       __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
       __ bind(done);
       // get the new MH:
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -741,7 +737,7 @@
       assert(CONV_VMINFO_SHIFT == 0, "preshifted");
 
       // get the new MH:
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       // (now we are done with the old MH)
 
       // original 32-bit vmdata word must be of this form:
@@ -816,7 +812,7 @@
         ShouldNotReachHere();
       }
 
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -858,7 +854,7 @@
                          rax_argslot, rbx_temp, rdx_temp);
       }
 
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -969,7 +965,7 @@
         }
       }
 
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -1029,7 +1025,7 @@
 
       __ pop(rdi);              // restore temp
 
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -1052,7 +1048,7 @@
 
       __ pop(rdi);              // restore temp
 
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -1103,8 +1099,8 @@
 
       // Check the array type.
       Register rbx_klass = rbx_temp;
-      __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
-      __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
+      __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
+      __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
 
       Label ok_array_klass, bad_array_klass, bad_array_length;
       __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass);
@@ -1186,7 +1182,7 @@
 
       // Arguments are spread.  Move to next method handle.
       UNPUSH_RSI_RDI;
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
+      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
 
       __ bind(bad_array_klass);
--- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -35,7 +35,7 @@
 
 // MethodHandles adapters
 enum method_handles_platform_dependent_constants {
-  method_handles_adapters_code_size = 26000
+  method_handles_adapters_code_size = 40000
 };
 
 class x86 {
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -3111,19 +3111,22 @@
 
   // rax: CallSite object (f1)
   // rbx: unused (f2)
+  // rcx: receiver address
   // rdx: flags (unused)
 
+  Register rax_callsite      = rax;
+  Register rcx_method_handle = rcx;
+
   if (ProfileInterpreter) {
-    Label L;
     // %%% should make a type profile for any invokedynamic that takes a ref argument
     // profile this call
     __ profile_call(rsi);
   }
 
-  __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
-  __ null_check(rcx);
+  __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+  __ null_check(rcx_method_handle);
   __ prepare_to_jump_from_interpreted();
-  __ jump_to_method_handle_entry(rcx, rdx);
+  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
 }
 
 //----------------------------------------------------------------------------------------------------
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -3120,17 +3120,19 @@
   // rcx: receiver address
   // rdx: flags (unused)
 
+  Register rax_callsite      = rax;
+  Register rcx_method_handle = rcx;
+
   if (ProfileInterpreter) {
-    Label L;
     // %%% should make a type profile for any invokedynamic that takes a ref argument
     // profile this call
     __ profile_call(r13);
   }
 
-  __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
-  __ null_check(rcx);
+  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+  __ null_check(rcx_method_handle);
   __ prepare_to_jump_from_interpreted();
-  __ jump_to_method_handle_entry(rcx, rdx);
+  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
 }
 
 
--- a/src/cpu/zero/vm/interpreterRT_zero.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/cpu/zero/vm/interpreterRT_zero.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -92,15 +92,15 @@
 
  public:
   SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer)
-    : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()),
+    : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->insts_end()),
       _cb(buffer) {
-    _cb->set_code_end((address) (cif() + 1));
+    _cb->set_insts_end((address) (cif() + 1));
   }
 
  private:
   void push(intptr_t value) {
-    intptr_t *dst = (intptr_t *) _cb->code_end();
-    _cb->set_code_end((address) (dst + 1));
+    intptr_t *dst = (intptr_t *) _cb->insts_end();
+    _cb->set_insts_end((address) (dst + 1));
     *dst = value;
   }
 };
--- a/src/share/vm/asm/codeBuffer.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/asm/codeBuffer.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -168,8 +168,8 @@
   bool allocates(address pc) const  { return pc >= _start && pc <  _limit; }
   bool allocates2(address pc) const { return pc >= _start && pc <= _limit; }
 
-  void    set_end(address pc)       { assert(allocates2(pc),""); _end = pc; }
-  void    set_mark(address pc)      { assert(contains2(pc),"not in codeBuffer");
+  void    set_end(address pc)       { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT, _start, pc, _limit)); _end = pc; }
+  void    set_mark(address pc)      { assert(contains2(pc), "not in codeBuffer");
                                       _mark = pc; }
   void    set_mark_off(int offset)  { assert(contains2(offset+_start),"not in codeBuffer");
                                       _mark = offset + _start; }
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1350,6 +1350,7 @@
     addr = ptr;
   }
   assert(addr->is_register(), "must be a register at this point");
+  assert(addr->type() == T_OBJECT, "addr should point to an object");
 
   LIR_Opr xor_res = new_pointer_register();
   LIR_Opr xor_shift_res = new_pointer_register();
--- a/src/share/vm/ci/ciInstanceKlass.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/ci/ciInstanceKlass.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -471,7 +471,7 @@
     ciField* field = fields->at(i);
     int offset = field->offset_in_bytes();
     int size   = (field->_type == NULL) ? heapOopSize : field->size_in_bytes();
-    assert(last_offset <= offset, "no field overlap");
+    assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset));
     if (last_offset > (int)sizeof(oopDesc))
       assert((offset - last_offset) < BytesPerLong, "no big holes");
     // Note:  Two consecutive T_BYTE fields will be separated by wordSize-1
--- a/src/share/vm/ci/ciTypeFlow.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/ci/ciTypeFlow.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1945,7 +1945,7 @@
   _has_irreducible_entry = false;
   _osr_bci = osr_bci;
   _failure_reason = NULL;
-  assert(start_bci() >= 0 && start_bci() < code_size() , "correct osr_bci argument");
+  assert(0 <= start_bci() && start_bci() < code_size() , err_msg("correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size()));
   _work_list = NULL;
 
   _ciblock_count = _methodBlocks->num_blocks();
--- a/src/share/vm/classfile/classFileParser.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -2702,13 +2702,15 @@
       // Adjust the field type from byte to an unmanaged pointer.
       assert(fac_ptr->nonstatic_byte_count > 0, "");
       fac_ptr->nonstatic_byte_count -= 1;
-      (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
-                                   word_sig_index);
-      fac_ptr->nonstatic_word_count += 1;
+
+      (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index);
+      assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64");
+      if (wordSize == longSize)  fac_ptr->nonstatic_double_count += 1;
+      else                       fac_ptr->nonstatic_word_count   += 1;
 
       FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset);
       assert(atype == NONSTATIC_BYTE, "");
-      FieldAllocationType new_atype = NONSTATIC_WORD;
+      FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD;
       (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype);
 
       found_vmentry = true;
--- a/src/share/vm/code/nmethod.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/code/nmethod.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1421,7 +1421,7 @@
   }
 
 #ifdef SHARK
-  ((SharkCompiler *) compiler())->free_compiled_method(instructions_begin());
+  ((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
 #endif // SHARK
 
   ((CodeBlob*)(this))->flush();
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -791,7 +791,7 @@
   int                _worker_i;
 public:
   RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) :
-    _cl(g1->g1_rem_set()->as_HRInto_G1RemSet(), worker_i),
+    _cl(g1->g1_rem_set(), worker_i),
     _worker_i(worker_i),
     _g1h(g1)
   { }
@@ -890,7 +890,7 @@
     abandon_cur_alloc_region();
     abandon_gc_alloc_regions();
     assert(_cur_alloc_region == NULL, "Invariant.");
-    g1_rem_set()->as_HRInto_G1RemSet()->cleanupHRRS();
+    g1_rem_set()->cleanupHRRS();
     tear_down_region_lists();
     set_used_regions_to_need_zero_fill();
 
@@ -1506,15 +1506,11 @@
   }
 
   // Also create a G1 rem set.
-  if (G1UseHRIntoRS) {
-    if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
-      _g1_rem_set = new HRInto_G1RemSet(this, (CardTableModRefBS*)mr_bs());
-    } else {
-      vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
-      return JNI_ENOMEM;
-    }
+  if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
+    _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
   } else {
-    _g1_rem_set = new StupidG1RemSet(this);
+    vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
+    return JNI_ENOMEM;
   }
 
   // Carve out the G1 part of the heap.
@@ -2706,8 +2702,7 @@
 }
 
 size_t G1CollectedHeap::cards_scanned() {
-  HRInto_G1RemSet* g1_rset = (HRInto_G1RemSet*) g1_rem_set();
-  return g1_rset->cardsScanned();
+  return g1_rem_set()->cardsScanned();
 }
 
 void
@@ -3850,6 +3845,54 @@
                undo_waste() * HeapWordSize / K);
 }
 
+#ifdef ASSERT
+bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
+  assert(ref != NULL, "invariant");
+  assert(UseCompressedOops, "sanity");
+  assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref));
+  oop p = oopDesc::load_decode_heap_oop(ref);
+  assert(_g1h->is_in_g1_reserved(p),
+         err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
+  return true;
+}
+
+bool G1ParScanThreadState::verify_ref(oop* ref) const {
+  assert(ref != NULL, "invariant");
+  if (has_partial_array_mask(ref)) {
+    // Must be in the collection set--it's already been copied.
+    oop p = clear_partial_array_mask(ref);
+    assert(_g1h->obj_in_cs(p),
+           err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
+  } else {
+    oop p = oopDesc::load_decode_heap_oop(ref);
+    assert(_g1h->is_in_g1_reserved(p),
+           err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
+  }
+  return true;
+}
+
+bool G1ParScanThreadState::verify_task(StarTask ref) const {
+  if (ref.is_narrow()) {
+    return verify_ref((narrowOop*) ref);
+  } else {
+    return verify_ref((oop*) ref);
+  }
+}
+#endif // ASSERT
+
+void G1ParScanThreadState::trim_queue() {
+  StarTask ref;
+  do {
+    // Drain the overflow stack first, so other threads can steal.
+    while (refs()->pop_overflow(ref)) {
+      deal_with_reference(ref);
+    }
+    while (refs()->pop_local(ref)) {
+      deal_with_reference(ref);
+    }
+  } while (!refs()->is_empty());
+}
+
 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
   _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
   _par_scan_state(par_scan_state) { }
@@ -4052,38 +4095,39 @@
     : _g1h(g1h), _par_scan_state(par_scan_state),
       _queues(queues), _terminator(terminator) {}
 
-  void do_void() {
-    G1ParScanThreadState* pss = par_scan_state();
-    while (true) {
+  void do_void();
+
+private:
+  inline bool offer_termination();
+};
+
+bool G1ParEvacuateFollowersClosure::offer_termination() {
+  G1ParScanThreadState* const pss = par_scan_state();
+  pss->start_term_time();
+  const bool res = terminator()->offer_termination();
+  pss->end_term_time();
+  return res;
+}
+
+void G1ParEvacuateFollowersClosure::do_void() {
+  StarTask stolen_task;
+  G1ParScanThreadState* const pss = par_scan_state();
+  pss->trim_queue();
+
+  do {
+    while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) {
+      assert(pss->verify_task(stolen_task), "sanity");
+      if (stolen_task.is_narrow()) {
+        pss->push_on_queue((narrowOop*) stolen_task);
+      } else {
+        pss->push_on_queue((oop*) stolen_task);
+      }
       pss->trim_queue();
-
-      StarTask stolen_task;
-      if (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) {
-        // slightly paranoid tests; I'm trying to catch potential
-        // problems before we go into push_on_queue to know where the
-        // problem is coming from
-        assert((oop*)stolen_task != NULL, "Error");
-        if (stolen_task.is_narrow()) {
-          assert(UseCompressedOops, "Error");
-          narrowOop* p = (narrowOop*) stolen_task;
-          assert(has_partial_array_mask(p) ||
-                 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "Error");
-          pss->push_on_queue(p);
-        } else {
-          oop* p = (oop*) stolen_task;
-          assert(has_partial_array_mask(p) || _g1h->is_in_g1_reserved(*p), "Error");
-          pss->push_on_queue(p);
-        }
-        continue;
-      }
-      pss->start_term_time();
-      if (terminator()->offer_termination()) break;
-      pss->end_term_time();
     }
-    pss->end_term_time();
-    pss->retire_alloc_buffers();
-  }
-};
+  } while (!offer_termination());
+
+  pss->retire_alloc_buffers();
+}
 
 class G1ParTask : public AbstractGangTask {
 protected:
@@ -4182,8 +4226,7 @@
       pss.print_termination_stats(i);
     }
 
-    assert(pss.refs_to_scan() == 0, "Task queue should be empty");
-    assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty");
+    assert(pss.refs()->is_empty(), "should be empty");
     double end_time_ms = os::elapsedTime() * 1000.0;
     _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms);
   }
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1651,49 +1651,17 @@
   size_t alloc_buffer_waste() const              { return _alloc_buffer_waste; }
   size_t undo_waste() const                      { return _undo_waste; }
 
+#ifdef ASSERT
+  bool verify_ref(narrowOop* ref) const;
+  bool verify_ref(oop* ref) const;
+  bool verify_task(StarTask ref) const;
+#endif // ASSERT
+
   template <class T> void push_on_queue(T* ref) {
-    assert(ref != NULL, "invariant");
-    assert(has_partial_array_mask(ref) ||
-           _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(ref)), "invariant");
-#ifdef ASSERT
-    if (has_partial_array_mask(ref)) {
-      oop p = clear_partial_array_mask(ref);
-      // Verify that we point into the CS
-      assert(_g1h->obj_in_cs(p), "Should be in CS");
-    }
-#endif
+    assert(verify_ref(ref), "sanity");
     refs()->push(ref);
   }
 
-  void pop_from_queue(StarTask& ref) {
-    if (refs()->pop_local(ref)) {
-      assert((oop*)ref != NULL, "pop_local() returned true");
-      assert(UseCompressedOops || !ref.is_narrow(), "Error");
-      assert(has_partial_array_mask((oop*)ref) ||
-             _g1h->is_in_g1_reserved(ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)ref)
-                                                     : oopDesc::load_decode_heap_oop((oop*)ref)),
-              "invariant");
-    } else {
-      StarTask null_task;
-      ref = null_task;
-    }
-  }
-
-  void pop_from_overflow_queue(StarTask& ref) {
-    StarTask new_ref;
-    refs()->pop_overflow(new_ref);
-    assert((oop*)new_ref != NULL, "pop() from a local non-empty stack");
-    assert(UseCompressedOops || !new_ref.is_narrow(), "Error");
-    assert(has_partial_array_mask((oop*)new_ref) ||
-           _g1h->is_in_g1_reserved(new_ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)new_ref)
-                                                       : oopDesc::load_decode_heap_oop((oop*)new_ref)),
-           "invariant");
-    ref = new_ref;
-  }
-
-  int refs_to_scan()            { return (int)refs()->size(); }
-  int overflowed_refs_to_scan() { return (int)refs()->overflow_stack()->size(); }
-
   template <class T> void update_rs(HeapRegion* from, T* p, int tid) {
     if (G1DeferredRSUpdate) {
       deferred_rs_update(from, p, tid);
@@ -1818,59 +1786,15 @@
     }
   }
 
-public:
-  void trim_queue() {
-    // I've replicated the loop twice, first to drain the overflow
-    // queue, second to drain the task queue. This is better than
-    // having a single loop, which checks both conditions and, inside
-    // it, either pops the overflow queue or the task queue, as each
-    // loop is tighter. Also, the decision to drain the overflow queue
-    // first is not arbitrary, as the overflow queue is not visible
-    // to the other workers, whereas the task queue is. So, we want to
-    // drain the "invisible" entries first, while allowing the other
-    // workers to potentially steal the "visible" entries.
-
-    while (refs_to_scan() > 0 || overflowed_refs_to_scan() > 0) {
-      while (overflowed_refs_to_scan() > 0) {
-        StarTask ref_to_scan;
-        assert((oop*)ref_to_scan == NULL, "Constructed above");
-        pop_from_overflow_queue(ref_to_scan);
-        // We shouldn't have pushed it on the queue if it was not
-        // pointing into the CSet.
-        assert((oop*)ref_to_scan != NULL, "Follows from inner loop invariant");
-        if (ref_to_scan.is_narrow()) {
-          assert(UseCompressedOops, "Error");
-          narrowOop* p = (narrowOop*)ref_to_scan;
-          assert(!has_partial_array_mask(p) &&
-                 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
-          deal_with_reference(p);
-        } else {
-          oop* p = (oop*)ref_to_scan;
-          assert((has_partial_array_mask(p) && _g1h->is_in_g1_reserved(clear_partial_array_mask(p))) ||
-                 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
-          deal_with_reference(p);
-        }
-      }
-
-      while (refs_to_scan() > 0) {
-        StarTask ref_to_scan;
-        assert((oop*)ref_to_scan == NULL, "Constructed above");
-        pop_from_queue(ref_to_scan);
-        if ((oop*)ref_to_scan != NULL) {
-          if (ref_to_scan.is_narrow()) {
-            assert(UseCompressedOops, "Error");
-            narrowOop* p = (narrowOop*)ref_to_scan;
-            assert(!has_partial_array_mask(p) &&
-                    _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
-            deal_with_reference(p);
-          } else {
-            oop* p = (oop*)ref_to_scan;
-            assert((has_partial_array_mask(p) && _g1h->obj_in_cs(clear_partial_array_mask(p))) ||
-                   _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
-            deal_with_reference(p);
-          }
-        }
-      }
+  void deal_with_reference(StarTask ref) {
+    assert(verify_task(ref), "sanity");
+    if (ref.is_narrow()) {
+      deal_with_reference((narrowOop*)ref);
+    } else {
+      deal_with_reference((oop*)ref);
     }
   }
+
+public:
+  void trim_queue();
 };
--- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -25,8 +25,6 @@
 class HeapRegion;
 class G1CollectedHeap;
 class G1RemSet;
-class HRInto_G1RemSet;
-class G1RemSet;
 class ConcurrentMark;
 class DirtyCardToOopClosure;
 class CMBitMap;
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -97,13 +97,6 @@
   }
 };
 
-void
-StupidG1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
-                                            int worker_i) {
-  IntoCSRegionClosure rc(_g1, oc);
-  _g1->heap_region_iterate(&rc);
-}
-
 class VerifyRSCleanCardOopClosure: public OopClosure {
   G1CollectedHeap* _g1;
 public:
@@ -119,8 +112,9 @@
   }
 };
 
-HRInto_G1RemSet::HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
-  : G1RemSet(g1), _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
+G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
+  : _g1(g1), _conc_refine_cards(0),
+    _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
     _cg1r(g1->concurrent_g1_refine()),
     _traversal_in_progress(false),
     _cset_rs_update_cl(NULL),
@@ -134,7 +128,7 @@
   }
 }
 
-HRInto_G1RemSet::~HRInto_G1RemSet() {
+G1RemSet::~G1RemSet() {
   delete _seq_task;
   for (uint i = 0; i < n_workers(); i++) {
     assert(_cset_rs_update_cl[i] == NULL, "it should be");
@@ -277,7 +271,7 @@
 //          p threads
 // Then thread t will start at region t * floor (n/p)
 
-HeapRegion* HRInto_G1RemSet::calculateStartRegion(int worker_i) {
+HeapRegion* G1RemSet::calculateStartRegion(int worker_i) {
   HeapRegion* result = _g1p->collection_set();
   if (ParallelGCThreads > 0) {
     size_t cs_size = _g1p->collection_set_size();
@@ -290,7 +284,7 @@
   return result;
 }
 
-void HRInto_G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
+void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
   double rs_time_start = os::elapsedTime();
   HeapRegion *startRegion = calculateStartRegion(worker_i);
 
@@ -340,7 +334,7 @@
   }
 };
 
-void HRInto_G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
+void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
   double start = os::elapsedTime();
   // Apply the given closure to all remaining log entries.
   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
@@ -439,12 +433,11 @@
   }
 };
 
-void HRInto_G1RemSet::cleanupHRRS() {
+void G1RemSet::cleanupHRRS() {
   HeapRegionRemSet::cleanup();
 }
 
-void
-HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
+void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
                                              int worker_i) {
 #if CARD_REPEAT_HISTO
   ct_freq_update_histo_and_reset();
@@ -508,8 +501,7 @@
   _cset_rs_update_cl[worker_i] = NULL;
 }
 
-void HRInto_G1RemSet::
-prepare_for_oops_into_collection_set_do() {
+void G1RemSet::prepare_for_oops_into_collection_set_do() {
 #if G1_REM_SET_LOGGING
   PrintRSClosure cl;
   _g1->collection_set_iterate(&cl);
@@ -581,7 +573,7 @@
     //   RSet updating,
     // * the post-write barrier shouldn't be logging updates to young
     //   regions (but there is a situation where this can happen - see
-    //   the comment in HRInto_G1RemSet::concurrentRefineOneCard below -
+    //   the comment in G1RemSet::concurrentRefineOneCard below -
     //   that should not be applicable here), and
     // * during actual RSet updating, the filtering of cards in young
     //   regions in HeapRegion::oops_on_card_seq_iterate_careful is
@@ -601,7 +593,7 @@
   }
 };
 
-void HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do() {
+void G1RemSet::cleanup_after_oops_into_collection_set_do() {
   guarantee( _cards_scanned != NULL, "invariant" );
   _total_cards_scanned = 0;
   for (uint i = 0; i < n_workers(); ++i)
@@ -692,12 +684,12 @@
   }
 };
 
-void HRInto_G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
+void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
   ScrubRSClosure scrub_cl(region_bm, card_bm);
   _g1->heap_region_iterate(&scrub_cl);
 }
 
-void HRInto_G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
+void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
                                 int worker_num, int claim_val) {
   ScrubRSClosure scrub_cl(region_bm, card_bm);
   _g1->heap_region_par_iterate_chunked(&scrub_cl, worker_num, claim_val);
@@ -741,7 +733,7 @@
   virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
 };
 
-bool HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
+bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
                                                    bool check_for_refs_into_cset) {
   // Construct the region representing the card.
   HeapWord* start = _ct_bs->addr_for(card_ptr);
@@ -820,7 +812,7 @@
   return trigger_cl.value();
 }
 
-bool HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
+bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
                                               bool check_for_refs_into_cset) {
   // If the card is no longer dirty, nothing to do.
   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
@@ -995,7 +987,7 @@
   }
 };
 
-void HRInto_G1RemSet::print_summary_info() {
+void G1RemSet::print_summary_info() {
   G1CollectedHeap* g1 = G1CollectedHeap::heap();
 
 #if CARD_REPEAT_HISTO
@@ -1029,30 +1021,26 @@
   g1->concurrent_g1_refine()->threads_do(&p);
   gclog_or_tty->print_cr("");
 
-  if (G1UseHRIntoRS) {
-    HRRSStatsIter blk;
-    g1->heap_region_iterate(&blk);
-    gclog_or_tty->print_cr("  Total heap region rem set sizes = " SIZE_FORMAT "K."
-                           "  Max = " SIZE_FORMAT "K.",
-                           blk.total_mem_sz()/K, blk.max_mem_sz()/K);
-    gclog_or_tty->print_cr("  Static structures = " SIZE_FORMAT "K,"
-                           " free_lists = " SIZE_FORMAT "K.",
-                           HeapRegionRemSet::static_mem_size()/K,
-                           HeapRegionRemSet::fl_mem_size()/K);
-    gclog_or_tty->print_cr("    %d occupied cards represented.",
-                           blk.occupied());
-    gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
-                           ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
-                           blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
-                           (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
-                           (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
-    gclog_or_tty->print_cr("    Did %d coarsenings.",
-                  HeapRegionRemSet::n_coarsenings());
-
-  }
+  HRRSStatsIter blk;
+  g1->heap_region_iterate(&blk);
+  gclog_or_tty->print_cr("  Total heap region rem set sizes = " SIZE_FORMAT "K."
+                         "  Max = " SIZE_FORMAT "K.",
+                         blk.total_mem_sz()/K, blk.max_mem_sz()/K);
+  gclog_or_tty->print_cr("  Static structures = " SIZE_FORMAT "K,"
+                         " free_lists = " SIZE_FORMAT "K.",
+                         HeapRegionRemSet::static_mem_size()/K,
+                         HeapRegionRemSet::fl_mem_size()/K);
+  gclog_or_tty->print_cr("    %d occupied cards represented.",
+                         blk.occupied());
+  gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
+                         ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
+                         blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
+                         (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
+                         (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
+  gclog_or_tty->print_cr("    Did %d coarsenings.", HeapRegionRemSet::n_coarsenings());
 }
 
-void HRInto_G1RemSet::prepare_for_verify() {
+void G1RemSet::prepare_for_verify() {
   if (G1HRRSFlushLogBuffersOnVerify &&
       (VerifyBeforeGC || VerifyAfterGC)
       &&  !_g1->full_collection()) {
--- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -27,107 +27,18 @@
 
 class G1CollectedHeap;
 class CardTableModRefBarrierSet;
-class HRInto_G1RemSet;
 class ConcurrentG1Refine;
 
+// A G1RemSet in which each heap region has a rem set that records the
+// external heap references into it.  Uses a mod ref bs to track updates,
+// so that they can be used to update the individual region remsets.
+
 class G1RemSet: public CHeapObj {
 protected:
   G1CollectedHeap* _g1;
   unsigned _conc_refine_cards;
   size_t n_workers();
 
-public:
-  G1RemSet(G1CollectedHeap* g1) :
-    _g1(g1), _conc_refine_cards(0)
-  {}
-
-  // Invoke "blk->do_oop" on all pointers into the CS in object in regions
-  // outside the CS (having invoked "blk->set_region" to set the "from"
-  // region correctly beforehand.) The "worker_i" param is for the
-  // parallel case where the number of the worker thread calling this
-  // function can be helpful in partitioning the work to be done. It
-  // should be the same as the "i" passed to the calling thread's
-  // work(i) function. In the sequential case this param will be ingored.
-  virtual void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
-                                           int worker_i) = 0;
-
-  // Prepare for and cleanup after an oops_into_collection_set_do
-  // call.  Must call each of these once before and after (in sequential
-  // code) any threads call oops into collection set do.  (This offers an
-  // opportunity to sequential setup and teardown of structures needed by a
-  // parallel iteration over the CS's RS.)
-  virtual void prepare_for_oops_into_collection_set_do() = 0;
-  virtual void cleanup_after_oops_into_collection_set_do() = 0;
-
-  // If "this" is of the given subtype, return "this", else "NULL".
-  virtual HRInto_G1RemSet* as_HRInto_G1RemSet() { return NULL; }
-
-  // Record, if necessary, the fact that *p (where "p" is in region "from",
-  // and is, a fortiori, required to be non-NULL) has changed to its new value.
-  virtual void write_ref(HeapRegion* from, oop* p) = 0;
-  virtual void write_ref(HeapRegion* from, narrowOop* p) = 0;
-  virtual void par_write_ref(HeapRegion* from, oop* p, int tid) = 0;
-  virtual void par_write_ref(HeapRegion* from, narrowOop* p, int tid) = 0;
-
-  // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
-  // or card, respectively, such that a region or card with a corresponding
-  // 0 bit contains no part of any live object.  Eliminates any remembered
-  // set entries that correspond to dead heap ranges.
-  virtual void scrub(BitMap* region_bm, BitMap* card_bm) = 0;
-  // Like the above, but assumes is called in parallel: "worker_num" is the
-  // parallel thread id of the current thread, and "claim_val" is the
-  // value that should be used to claim heap regions.
-  virtual void scrub_par(BitMap* region_bm, BitMap* card_bm,
-                         int worker_num, int claim_val) = 0;
-
-  // Refine the card corresponding to "card_ptr".  If "sts" is non-NULL,
-  // join and leave around parts that must be atomic wrt GC.  (NULL means
-  // being done at a safepoint.)
-  // With some implementations of this routine, when check_for_refs_into_cset
-  // is true, a true result may be returned if the given card contains oops
-  // that have references into the current collection set.
-  virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
-                                       bool check_for_refs_into_cset) {
-    return false;
-  }
-
-  // Print any relevant summary info.
-  virtual void print_summary_info() {}
-
-  // Prepare remebered set for verification.
-  virtual void prepare_for_verify() {};
-};
-
-
-// The simplest possible G1RemSet: iterates over all objects in non-CS
-// regions, searching for pointers into the CS.
-class StupidG1RemSet: public G1RemSet {
-public:
-  StupidG1RemSet(G1CollectedHeap* g1) : G1RemSet(g1) {}
-
-  void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
-                                   int worker_i);
-
-  void prepare_for_oops_into_collection_set_do() {}
-  void cleanup_after_oops_into_collection_set_do() {}
-
-  // Nothing is necessary in the version below.
-  void write_ref(HeapRegion* from, oop* p) {}
-  void write_ref(HeapRegion* from, narrowOop* p) {}
-  void par_write_ref(HeapRegion* from, oop* p, int tid) {}
-  void par_write_ref(HeapRegion* from, narrowOop* p, int tid) {}
-
-  void scrub(BitMap* region_bm, BitMap* card_bm) {}
-  void scrub_par(BitMap* region_bm, BitMap* card_bm,
-                 int worker_num, int claim_val) {}
-
-};
-
-// A G1RemSet in which each heap region has a rem set that records the
-// external heap references into it.  Uses a mod ref bs to track updates,
-// so that they can be used to update the individual region remsets.
-
-class HRInto_G1RemSet: public G1RemSet {
 protected:
   enum SomePrivateConstants {
     UpdateRStoMergeSync  = 0,
@@ -175,28 +86,32 @@
   // scanned.
   void cleanupHRRS();
 
-  HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
-  ~HRInto_G1RemSet();
+  G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
+  ~G1RemSet();
 
+  // Invoke "blk->do_oop" on all pointers into the CS in objects in regions
+  // outside the CS (having invoked "blk->set_region" to set the "from"
+  // region correctly beforehand.) The "worker_i" param is for the
+  // parallel case where the number of the worker thread calling this
+  // function can be helpful in partitioning the work to be done. It
+  // should be the same as the "i" passed to the calling thread's
+  // work(i) function. In the sequential case this param will be ingored.
   void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
                                    int worker_i);
 
+  // Prepare for and cleanup after an oops_into_collection_set_do
+  // call.  Must call each of these once before and after (in sequential
+  // code) any threads call oops_into_collection_set_do.  (This offers an
+  // opportunity to sequential setup and teardown of structures needed by a
+  // parallel iteration over the CS's RS.)
   void prepare_for_oops_into_collection_set_do();
   void cleanup_after_oops_into_collection_set_do();
+
   void scanRS(OopsInHeapRegionClosure* oc, int worker_i);
-  template <class T> void scanNewRefsRS_work(OopsInHeapRegionClosure* oc, int worker_i);
-  void scanNewRefsRS(OopsInHeapRegionClosure* oc, int worker_i) {
-    if (UseCompressedOops) {
-      scanNewRefsRS_work<narrowOop>(oc, worker_i);
-    } else {
-      scanNewRefsRS_work<oop>(oc, worker_i);
-    }
-  }
   void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i);
+
   HeapRegion* calculateStartRegion(int i);
 
-  HRInto_G1RemSet* as_HRInto_G1RemSet() { return this; }
-
   CardTableModRefBS* ct_bs() { return _ct_bs; }
   size_t cardsScanned() { return _total_cards_scanned; }
 
@@ -219,17 +134,31 @@
 
   bool self_forwarded(oop obj);
 
+  // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
+  // or card, respectively, such that a region or card with a corresponding
+  // 0 bit contains no part of any live object.  Eliminates any remembered
+  // set entries that correspond to dead heap ranges.
   void scrub(BitMap* region_bm, BitMap* card_bm);
+
+  // Like the above, but assumes is called in parallel: "worker_num" is the
+  // parallel thread id of the current thread, and "claim_val" is the
+  // value that should be used to claim heap regions.
   void scrub_par(BitMap* region_bm, BitMap* card_bm,
                  int worker_num, int claim_val);
 
-  // If check_for_refs_into_cset is true then a true result is returned
-  // if the card contains oops that have references into the current
-  // collection set.
+  // Refine the card corresponding to "card_ptr".  If "sts" is non-NULL,
+  // join and leave around parts that must be atomic wrt GC.  (NULL means
+  // being done at a safepoint.)
+  // If check_for_refs_into_cset is true, a true result is returned
+  // if the given card contains oops that have references into the
+  // current collection set.
   virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
                                        bool check_for_refs_into_cset);
 
+  // Print any relevant summary info.
   virtual void print_summary_info();
+
+  // Prepare remembered set for verification.
   virtual void prepare_for_verify();
 };
 
@@ -250,13 +179,13 @@
 
 class UpdateRSOopClosure: public OopClosure {
   HeapRegion* _from;
-  HRInto_G1RemSet* _rs;
+  G1RemSet* _rs;
   int _worker_i;
 
   template <class T> void do_oop_work(T* p);
 
 public:
-  UpdateRSOopClosure(HRInto_G1RemSet* rs, int worker_i = 0) :
+  UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) :
     _from(NULL), _rs(rs), _worker_i(worker_i) {
     guarantee(_rs != NULL, "Requires an HRIntoG1RemSet");
   }
--- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -30,16 +30,18 @@
   }
 }
 
-template <class T> inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
+template <class T>
+inline void G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
   par_write_ref_nv(from, p, 0);
 }
 
-inline bool HRInto_G1RemSet::self_forwarded(oop obj) {
+inline bool G1RemSet::self_forwarded(oop obj) {
   bool result =  (obj->is_forwarded() && (obj->forwardee()== obj));
   return result;
 }
 
-template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
+template <class T>
+inline void G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
   oop obj = oopDesc::load_decode_heap_oop(p);
 #ifdef ASSERT
   // can't do because of races
@@ -77,7 +79,7 @@
       // Deferred updates to the CSet are either discarded (in the normal case),
       // or processed (if an evacuation failure occurs) at the end
       // of the collection.
-      // See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do().
+      // See G1RemSet::cleanup_after_oops_into_collection_set_do().
     } else {
 #if G1_REM_SET_LOGGING
       gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
@@ -91,12 +93,14 @@
   }
 }
 
-template <class T> inline void UpdateRSOopClosure::do_oop_work(T* p) {
+template <class T>
+inline void UpdateRSOopClosure::do_oop_work(T* p) {
   assert(_from != NULL, "from region must be non-NULL");
   _rs->par_write_ref(_from, p, _worker_i);
 }
 
-template <class T> inline void UpdateRSetImmediate::do_oop_work(T* p) {
+template <class T>
+inline void UpdateRSetImmediate::do_oop_work(T* p) {
   assert(_from->is_in_reserved(p), "paranoia");
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop) && !_from->is_survivor()) {
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -40,9 +40,6 @@
   develop(intx, G1PolicyVerbose, 0,                                         \
           "The verbosity level on G1 policy decisions")                     \
                                                                             \
-  develop(bool, G1UseHRIntoRS, true,                                        \
-          "Determines whether the 'advanced' HR Into rem set is used.")     \
-                                                                            \
   develop(intx, G1MarkingVerboseLevel, 0,                                   \
           "Level (0-4) of verboseness of the marking code")                 \
                                                                             \
--- a/src/share/vm/gc_implementation/includeDB_gc_g1	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/gc_implementation/includeDB_gc_g1	Fri Oct 15 15:12:04 2010 -0400
@@ -310,10 +310,16 @@
 
 heapRegionSeq.inline.hpp                heapRegionSeq.hpp
 
+instanceKlass.cpp                       g1RemSet.inline.hpp
+
+instanceRefKlass.cpp                    g1RemSet.inline.hpp
+
 klass.hpp				g1OopClosures.hpp
 
 memoryService.cpp                       g1MemoryPool.hpp
 
+objArrayKlass.cpp                       g1RemSet.inline.hpp
+
 ptrQueue.cpp                            allocation.hpp
 ptrQueue.cpp                            allocation.inline.hpp
 ptrQueue.cpp                            mutex.hpp
--- a/src/share/vm/oops/methodOop.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/oops/methodOop.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -758,7 +758,7 @@
 
   OrderAccess::storestore();
 #ifdef SHARK
-  mh->_from_interpreted_entry = code->instructions_begin();
+  mh->_from_interpreted_entry = code->insts_begin();
 #else
   mh->_from_compiled_entry = code->verified_entry_point();
   OrderAccess::storestore();
--- a/src/share/vm/oops/oop.inline.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/oops/oop.inline.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -173,7 +173,7 @@
   address base = Universe::narrow_oop_base();
   int    shift = Universe::narrow_oop_shift();
   oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
-  assert(check_obj_alignment(result), "Address not aligned");
+  assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
   return result;
 }
 
--- a/src/share/vm/opto/library_call.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/opto/library_call.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -4761,7 +4761,7 @@
       Node* cv = generate_checkcast_arraycopy(adr_type,
                                               dest_elem_klass,
                                               src, src_offset, dest, dest_offset,
-                                              copy_length);
+                                              ConvI2X(copy_length));
       if (cv == NULL)  cv = intcon(-1);  // failure (no stub available)
       checked_control = control();
       checked_i_o     = i_o();
@@ -5206,7 +5206,7 @@
   int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc);
   Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
   Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
-  Node* check_offset = _gvn.transform(n3);
+  Node* check_offset = ConvI2X(_gvn.transform(n3));
   Node* check_value  = dest_elem_klass;
 
   Node* src_start  = array_element_address(src,  src_offset,  T_OBJECT);
--- a/src/share/vm/opto/loopTransform.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/opto/loopTransform.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -2684,7 +2684,14 @@
                                                       fill_name, TypeAryPtr::get_array_body_type(t));
   call->init_req(TypeFunc::Parms+0, from);
   call->init_req(TypeFunc::Parms+1, store_value);
+#ifdef _LP64
+  len = new (C, 2) ConvI2LNode(len);
+  _igvn.register_new_node_with_optimizer(len);
+#endif
   call->init_req(TypeFunc::Parms+2, len);
+#ifdef _LP64
+  call->init_req(TypeFunc::Parms+3, C->top());
+#endif
   call->init_req( TypeFunc::Control, head->init_control());
   call->init_req( TypeFunc::I_O    , C->top() )        ;   // does no i/o
   call->init_req( TypeFunc::Memory ,  mem_phi->in(LoopNode::EntryControl) );
--- a/src/share/vm/opto/runtime.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/opto/runtime.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -646,12 +646,14 @@
 
 
 const TypeFunc* OptoRuntime::array_fill_Type() {
-  // create input type (domain)
-  const Type** fields = TypeTuple::fields(3);
-  fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
-  fields[TypeFunc::Parms+1] = TypeInt::INT;
-  fields[TypeFunc::Parms+2] = TypeInt::INT;
-  const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 3, fields);
+  // create input type (domain): pointer, int, size_t
+  const Type** fields = TypeTuple::fields(3 LP64_ONLY( + 1));
+  int argp = TypeFunc::Parms;
+  fields[argp++] = TypePtr::NOTNULL;
+  fields[argp++] = TypeInt::INT;
+  fields[argp++] = TypeX_X;               // size in whatevers (size_t)
+  LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
+  const TypeTuple *domain = TypeTuple::make(argp, fields);
 
   // create result type
   fields = TypeTuple::fields(1);
--- a/src/share/vm/prims/methodHandles.cpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/prims/methodHandles.cpp	Fri Oct 15 15:12:04 2010 -0400
@@ -1568,7 +1568,7 @@
     if (ptype != T_INT) {
       int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
       jint value = argument->int_field(value_offset);
-      int vminfo = adapter_subword_vminfo(ptype);
+      int vminfo = adapter_unbox_subword_vminfo(ptype);
       jint subword = truncate_subword_from_vminfo(value, vminfo);
       if (value != subword) {
         err = "bound subword value does not fit into the subword type";
@@ -2018,12 +2018,12 @@
         assert(src == T_INT || is_subword_type(src), "source is not float");
         // Subword-related cases are int -> {boolean,byte,char,short}.
         ek_opt = _adapter_opt_i2i;
-        vminfo = adapter_subword_vminfo(dest);
+        vminfo = adapter_prim_to_prim_subword_vminfo(dest);
         break;
       case 2 *4+ 1:
         if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
           ek_opt = _adapter_opt_l2i;
-          vminfo = adapter_subword_vminfo(dest);
+          vminfo = adapter_prim_to_prim_subword_vminfo(dest);
         } else if (src == T_DOUBLE && dest == T_FLOAT) {
           ek_opt = _adapter_opt_d2f;
         } else {
@@ -2051,7 +2051,7 @@
       switch (type2size[dest]) {
       case 1:
         ek_opt = _adapter_opt_unboxi;
-        vminfo = adapter_subword_vminfo(dest);
+        vminfo = adapter_unbox_subword_vminfo(dest);
         break;
       case 2:
         ek_opt = _adapter_opt_unboxl;
--- a/src/share/vm/prims/methodHandles.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/prims/methodHandles.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -226,11 +226,20 @@
   }
 
   enum { CONV_VMINFO_SIGN_FLAG = 0x80 };
-  static int adapter_subword_vminfo(BasicType dest) {
-    if (dest == T_BOOLEAN) return (BitsPerInt -  1);
-    if (dest == T_CHAR)    return (BitsPerInt - 16);
-    if (dest == T_BYTE)    return (BitsPerInt -  8) | CONV_VMINFO_SIGN_FLAG;
-    if (dest == T_SHORT)   return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG;
+  // Shift values for prim-to-prim conversions.
+  static int adapter_prim_to_prim_subword_vminfo(BasicType dest) {
+    if (dest == T_BOOLEAN) return (BitsPerInt - 1);  // boolean is 1 bit
+    if (dest == T_CHAR)    return (BitsPerInt - BitsPerShort);
+    if (dest == T_BYTE)    return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG;
+    if (dest == T_SHORT)   return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG;
+    return 0;                   // case T_INT
+  }
+  // Shift values for unboxing a primitive.
+  static int adapter_unbox_subword_vminfo(BasicType dest) {
+    if (dest == T_BOOLEAN) return (BitsPerInt - BitsPerByte );  // implemented as 1 byte
+    if (dest == T_CHAR)    return (BitsPerInt - BitsPerShort);
+    if (dest == T_BYTE)    return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG;
+    if (dest == T_SHORT)   return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG;
     return 0;                   // case T_INT
   }
   // Here is the transformation the i2i adapter must perform:
--- a/src/share/vm/shark/sharkCompiler.hpp	Wed Oct 13 11:46:46 2010 -0400
+++ b/src/share/vm/shark/sharkCompiler.hpp	Fri Oct 15 15:12:04 2010 -0400
@@ -103,8 +103,7 @@
   // Global access
  public:
   static SharkCompiler* compiler() {
-    AbstractCompiler *compiler =
-      CompileBroker::compiler(CompLevel_fast_compile);
+    AbstractCompiler *compiler = CompileBroker::compiler(CompLevel_simple);
     assert(compiler->is_shark() && compiler->is_initialized(), "should be");
     return (SharkCompiler *) compiler;
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6987555/Test6987555.java	Fri Oct 15 15:12:04 2010 -0400
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6987555
+ * @summary JSR 292 unboxing to a boolean value fails on big-endian SPARC
+ *
+ * @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555
+ */
+
+import java.dyn.*;
+
+public class Test6987555 {
+    private static final Class   CLASS = Test6987555.class;
+    private static final String  NAME  = "foo";
+    private static final boolean DEBUG = false;
+
+    public static void main(String[] args) throws Throwable {
+        testboolean();
+        testbyte();
+        testchar();
+        testshort();
+        testint();
+    }
+
+    // boolean
+    static void testboolean() throws Throwable {
+        doboolean(false);
+        doboolean(true);
+    }
+    static void doboolean(boolean x) throws Throwable {
+        if (DEBUG)  System.out.println("boolean=" + x);
+        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(boolean.class, boolean.class));
+        MethodHandle mh2 = mh1.asType(MethodType.methodType(boolean.class, Boolean.class));
+        boolean a = mh1.<boolean>invokeExact(x);
+        boolean b = mh2.<boolean>invokeExact(Boolean.valueOf(x));
+        assert a == b : a + " != " + b;
+    }
+
+    // byte
+    static void testbyte() throws Throwable {
+        byte[] a = new byte[] {
+            Byte.MIN_VALUE,
+            Byte.MIN_VALUE + 1,
+            -0x0F,
+            -1,
+            0,
+            1,
+            0x0F,
+            Byte.MAX_VALUE - 1,
+            Byte.MAX_VALUE
+        };
+        for (int i = 0; i < a.length; i++) {
+            dobyte(a[i]);
+        }
+    }
+    static void dobyte(byte x) throws Throwable {
+        if (DEBUG)  System.out.println("byte=" + x);
+        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(byte.class, byte.class));
+        MethodHandle mh2 = mh1.asType(MethodType.methodType(byte.class, Byte.class));
+        byte a = mh1.<byte>invokeExact(x);
+        byte b = mh2.<byte>invokeExact(Byte.valueOf(x));
+        assert a == b : a + " != " + b;
+    }
+
+    // char
+    static void testchar() throws Throwable {
+        char[] a = new char[] {
+            Character.MIN_VALUE,
+            Character.MIN_VALUE + 1,
+            0x000F,
+            0x00FF,
+            0x0FFF,
+            Character.MAX_VALUE - 1,
+            Character.MAX_VALUE
+        };
+        for (int i = 0; i < a.length; i++) {
+            dochar(a[i]);
+        }
+    }
+    static void dochar(char x) throws Throwable {
+        if (DEBUG)  System.out.println("char=" + x);
+        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(char.class, char.class));
+        MethodHandle mh2 = mh1.asType(MethodType.methodType(char.class, Character.class));
+        char a = mh1.<char>invokeExact(x);
+        char b = mh2.<char>invokeExact(Character.valueOf(x));
+        assert a == b : a + " != " + b;
+    }
+
+    // short
+    static void testshort() throws Throwable {
+        short[] a = new short[] {
+            Short.MIN_VALUE,
+            Short.MIN_VALUE + 1,
+            -0x0FFF,
+            -0x00FF,
+            -0x000F,
+            -1,
+            0,
+            1,
+            0x000F,
+            0x00FF,
+            0x0FFF,
+            Short.MAX_VALUE - 1,
+            Short.MAX_VALUE
+        };
+        for (int i = 0; i < a.length; i++) {
+            doshort(a[i]);
+        }
+    }
+    static void doshort(short x) throws Throwable {
+        if (DEBUG)  System.out.println("short=" + x);
+        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(short.class, short.class));
+        MethodHandle mh2 = mh1.asType(MethodType.methodType(short.class, Short.class));
+        short a = mh1.<short>invokeExact(x);
+        short b = mh2.<short>invokeExact(Short.valueOf(x));
+        assert a == b : a + " != " + b;
+    }
+
+    // int
+    static void testint() throws Throwable {
+        int[] a = new int[] {
+            Integer.MIN_VALUE,
+            Integer.MIN_VALUE + 1,
+            -0x00000FFF,
+            -0x000000FF,
+            -0x0000000F,
+            -1,
+            0,
+            1,
+            0x0000000F,
+            0x000000FF,
+            0x00000FFF,
+            Integer.MAX_VALUE - 1,
+            Integer.MAX_VALUE
+        };
+        for (int i = 0; i < a.length; i++) {
+            doint(a[i]);
+        }
+    }
+    static void doint(int x) throws Throwable {
+        if (DEBUG)  System.out.println("int=" + x);
+        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(int.class, int.class));
+        MethodHandle mh2 = mh1.asType(MethodType.methodType(int.class, Integer.class));
+        int a = mh1.<int>invokeExact(x);
+        int b = mh2.<int>invokeExact(Integer.valueOf(x));
+        assert a == b : a + " != " + b;
+    }
+
+    public static boolean foo(boolean i) { return i; }
+    public static byte    foo(byte    i) { return i; }
+    public static char    foo(char    i) { return i; }
+    public static short   foo(short   i) { return i; }
+    public static int     foo(int     i) { return i; }
+}