Merge

Fri, 15 Oct 2010 15:12:04 -0400

author
acorn
date
Fri, 15 Oct 2010 15:12:04 -0400
changeset 2227
beba40b26a79
parent 2226
75b0735b4d04
parent 2218
ee813f7b46e4
child 2229
75ab0162aa84

Merge

src/cpu/x86/vm/methodHandles_x86.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
     1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
     1.3 @@ -3094,11 +3094,10 @@
     1.4  void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
     1.5                                                Register temp_reg,
     1.6                                                Label& wrong_method_type) {
     1.7 -  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
     1.8    assert_different_registers(mtype_reg, mh_reg, temp_reg);
     1.9    // compare method type against that of the receiver
    1.10    RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg);
    1.11 -  ld_ptr(mh_reg, mhtype_offset, temp_reg);
    1.12 +  load_heap_oop(mh_reg, mhtype_offset, temp_reg);
    1.13    cmp(temp_reg, mtype_reg);
    1.14    br(Assembler::notEqual, false, Assembler::pn, wrong_method_type);
    1.15    delayed()->nop();
    1.16 @@ -3112,16 +3111,15 @@
    1.17  void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
    1.18                                                  Register temp_reg) {
    1.19    assert_different_registers(vmslots_reg, mh_reg, temp_reg);
    1.20 -  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
    1.21    // load mh.type.form.vmslots
    1.22    if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
    1.23      // hoist vmslots into every mh to avoid dependent load chain
    1.24 -    ld(    Address(mh_reg,    delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
    1.25 +    ld(           Address(mh_reg,    delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
    1.26    } else {
    1.27      Register temp2_reg = vmslots_reg;
    1.28 -    ld_ptr(Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
    1.29 -    ld_ptr(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
    1.30 -    ld(    Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
    1.31 +    load_heap_oop(Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
    1.32 +    load_heap_oop(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
    1.33 +    ld(           Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
    1.34    }
    1.35  }
    1.36  
    1.37 @@ -3130,9 +3128,8 @@
    1.38    assert(mh_reg == G3_method_handle, "caller must put MH object in G3");
    1.39    assert_different_registers(mh_reg, temp_reg);
    1.40  
    1.41 -  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
    1.42 -
    1.43    // pick out the interpreted side of the handler
    1.44 +  // NOTE: vmentry is not an oop!
    1.45    ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
    1.46  
    1.47    // off we go...
    1.48 @@ -4653,6 +4650,11 @@
    1.49    }
    1.50  }
    1.51  
    1.52 +void MacroAssembler::load_heap_oop(Register s1, RegisterOrConstant s2, Register d) {
    1.53 +  if (s2.is_constant())  load_heap_oop(s1, s2.as_constant(), d);
    1.54 +  else                   load_heap_oop(s1, s2.as_register(), d);
    1.55 +}
    1.56 +
    1.57  void MacroAssembler::store_heap_oop(Register d, Register s1, Register s2) {
    1.58    if (UseCompressedOops) {
    1.59      assert(s1 != d && s2 != d, "not enough registers");
     2.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Oct 13 11:46:46 2010 -0400
     2.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Oct 15 15:12:04 2010 -0400
     2.3 @@ -825,6 +825,12 @@
     2.4    // test if -4096 <= x <= 4095
     2.5    static bool is_simm13(int x) { return is_simm(x, 13); }
     2.6  
     2.7 +  // test if label is in simm16 range in words (wdisp16).
     2.8 +  bool is_in_wdisp16_range(Label& L) {
     2.9 +    intptr_t d = intptr_t(pc()) - intptr_t(target(L));
    2.10 +    return is_simm(d, 18);
    2.11 +  }
    2.12 +
    2.13    enum ASIs { // page 72, v9
    2.14      ASI_PRIMARY        = 0x80,
    2.15      ASI_PRIMARY_LITTLE = 0x88
    2.16 @@ -2103,6 +2109,7 @@
    2.17    void load_heap_oop(const Address& s, Register d);
    2.18    void load_heap_oop(Register s1, Register s2, Register d);
    2.19    void load_heap_oop(Register s1, int simm13a, Register d);
    2.20 +  void load_heap_oop(Register s1, RegisterOrConstant s2, Register d);
    2.21    void store_heap_oop(Register d, Register s1, Register s2);
    2.22    void store_heap_oop(Register d, Register s1, int simm13a);
    2.23    void store_heap_oop(Register d, const Address& a, int offset = 0);
    2.24 @@ -2225,7 +2232,7 @@
    2.25    void stop(const char* msg);                          // prints msg, dumps registers and stops execution
    2.26    void warn(const char* msg);                          // prints msg, but don't stop
    2.27    void untested(const char* what = "");
    2.28 -  void unimplemented(const char* what = "")              { char* b = new char[1024];  sprintf(b, "unimplemented: %s", what);  stop(b); }
    2.29 +  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, 1024, "unimplemented: %s", what);  stop(b); }
    2.30    void should_not_reach_here()                   { stop("should not reach here"); }
    2.31    void print_CPU_state();
    2.32  
     3.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
     3.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
     3.3 @@ -425,8 +425,13 @@
     3.4    Register pre_val_reg = pre_val()->as_register();
     3.5  
     3.6    ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false);
     3.7 -  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
     3.8 -                    pre_val_reg, _continuation);
     3.9 +  if (__ is_in_wdisp16_range(_continuation)) {
    3.10 +    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
    3.11 +                      pre_val_reg, _continuation);
    3.12 +  } else {
    3.13 +    __ cmp(pre_val_reg, G0);
    3.14 +    __ brx(Assembler::equal, false, Assembler::pn, _continuation);
    3.15 +  }
    3.16    __ delayed()->nop();
    3.17  
    3.18    __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
    3.19 @@ -452,8 +457,13 @@
    3.20    assert(new_val()->is_register(), "Precondition.");
    3.21    Register addr_reg = addr()->as_pointer_register();
    3.22    Register new_val_reg = new_val()->as_register();
    3.23 -  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
    3.24 -                    new_val_reg, _continuation);
    3.25 +  if (__ is_in_wdisp16_range(_continuation)) {
    3.26 +    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
    3.27 +                      new_val_reg, _continuation);
    3.28 +  } else {
    3.29 +    __ cmp(new_val_reg, G0);
    3.30 +    __ brx(Assembler::equal, false, Assembler::pn, _continuation);
    3.31 +  }
    3.32    __ delayed()->nop();
    3.33  
    3.34    __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id));
     4.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
     4.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
     4.3 @@ -664,7 +664,7 @@
     4.4    // Use temps to avoid kills
     4.5    LIR_Opr t1 = FrameMap::G1_opr;
     4.6    LIR_Opr t2 = FrameMap::G3_opr;
     4.7 -  LIR_Opr addr = new_pointer_register();
     4.8 +  LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
     4.9  
    4.10    // get address of field
    4.11    obj.load_item();
     5.1 --- a/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp	Wed Oct 13 11:46:46 2010 -0400
     5.2 +++ b/src/cpu/sparc/vm/c1_LinearScan_sparc.hpp	Fri Oct 15 15:12:04 2010 -0400
     5.3 @@ -64,7 +64,7 @@
     5.4      _first_reg = pd_first_callee_saved_reg;
     5.5      _last_reg = pd_last_callee_saved_reg;
     5.6      return true;
     5.7 -  } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT) {
     5.8 +  } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_ADDRESS) {
     5.9      _first_reg = pd_first_cpu_reg;
    5.10      _last_reg = pd_last_allocatable_cpu_reg;
    5.11      return true;
     6.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
     6.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
     6.3 @@ -27,6 +27,14 @@
     6.4  
     6.5  #define __ _masm->
     6.6  
     6.7 +#ifdef PRODUCT
     6.8 +#define BLOCK_COMMENT(str) /* nothing */
     6.9 +#else
    6.10 +#define BLOCK_COMMENT(str) __ block_comment(str)
    6.11 +#endif
    6.12 +
    6.13 +#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
    6.14 +
    6.15  address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
    6.16                                                  address interpreted_entry) {
    6.17    // Just before the actual machine code entry point, allocate space
    6.18 @@ -90,8 +98,8 @@
    6.19    }
    6.20  
    6.21    // given the MethodType, find out where the MH argument is buried
    6.22 -  __ ld_ptr(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)),        O0_argslot);
    6.23 -  __ ldsw(  Address(O0_argslot,     __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot);
    6.24 +  __ load_heap_oop(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)),        O0_argslot);
    6.25 +  __ ldsw(         Address(O0_argslot,     __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot);
    6.26    __ ld_ptr(__ argument_address(O0_argslot), G3_method_handle);
    6.27  
    6.28    __ check_method_handle_type(G5_method_type, G3_method_handle, O1_scratch, wrong_method_type);
    6.29 @@ -105,6 +113,7 @@
    6.30  static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) {
    6.31    // Verify that argslot lies within (Gargs, FP].
    6.32    Label L_ok, L_bad;
    6.33 +  BLOCK_COMMENT("{ verify_argslot");
    6.34  #ifdef _LP64
    6.35    __ add(FP, STACK_BIAS, temp_reg);
    6.36    __ cmp(argslot_reg, temp_reg);
    6.37 @@ -119,6 +128,7 @@
    6.38    __ bind(L_bad);
    6.39    __ stop(error_message);
    6.40    __ bind(L_ok);
    6.41 +  BLOCK_COMMENT("} verify_argslot");
    6.42  }
    6.43  #endif
    6.44  
    6.45 @@ -175,6 +185,7 @@
    6.46    //   for (temp = sp + size; temp < argslot; temp++)
    6.47    //     temp[-size] = temp[0]
    6.48    //   argslot -= size;
    6.49 +  BLOCK_COMMENT("insert_arg_slots {");
    6.50    RegisterOrConstant offset = __ regcon_sll_ptr(arg_slots, LogBytesPerWord, temp3_reg);
    6.51  
    6.52    // Keep the stack pointer 2*wordSize aligned.
    6.53 @@ -187,7 +198,7 @@
    6.54  
    6.55    {
    6.56      Label loop;
    6.57 -    __ bind(loop);
    6.58 +    __ BIND(loop);
    6.59      // pull one word down each time through the loop
    6.60      __ ld_ptr(Address(temp_reg, 0), temp2_reg);
    6.61      __ st_ptr(temp2_reg, Address(temp_reg, offset));
    6.62 @@ -199,6 +210,7 @@
    6.63  
    6.64    // Now move the argslot down, to point to the opened-up space.
    6.65    __ add(argslot_reg, offset, argslot_reg);
    6.66 +  BLOCK_COMMENT("} insert_arg_slots");
    6.67  }
    6.68  
    6.69  
    6.70 @@ -235,6 +247,7 @@
    6.71    }
    6.72  #endif // ASSERT
    6.73  
    6.74 +  BLOCK_COMMENT("remove_arg_slots {");
    6.75    // Pull up everything shallower than argslot.
    6.76    // Then remove the excess space on the stack.
    6.77    // The stacked return address gets pulled up with everything else.
    6.78 @@ -246,7 +259,7 @@
    6.79    __ sub(argslot_reg, wordSize, temp_reg);  // source pointer for copy
    6.80    {
    6.81      Label loop;
    6.82 -    __ bind(loop);
    6.83 +    __ BIND(loop);
    6.84      // pull one word up each time through the loop
    6.85      __ ld_ptr(Address(temp_reg, 0), temp2_reg);
    6.86      __ st_ptr(temp2_reg, Address(temp_reg, offset));
    6.87 @@ -265,29 +278,35 @@
    6.88    const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1);
    6.89    RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg);
    6.90    __ add(SP, masked_offset, SP);
    6.91 +  BLOCK_COMMENT("} remove_arg_slots");
    6.92  }
    6.93  
    6.94  
    6.95  #ifndef PRODUCT
    6.96  extern "C" void print_method_handle(oop mh);
    6.97  void trace_method_handle_stub(const char* adaptername,
    6.98 -                              oop mh) {
    6.99 -#if 0
   6.100 -                              intptr_t* entry_sp,
   6.101 -                              intptr_t* saved_sp,
   6.102 -                              intptr_t* saved_bp) {
   6.103 -  // called as a leaf from native code: do not block the JVM!
   6.104 -  intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
   6.105 -  intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
   6.106 -  printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
   6.107 -         adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
   6.108 -  if (last_sp != saved_sp)
   6.109 -    printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
   6.110 -#endif
   6.111 -
   6.112 +                              oopDesc* mh) {
   6.113    printf("MH %s mh="INTPTR_FORMAT"\n", adaptername, (intptr_t) mh);
   6.114    print_method_handle(mh);
   6.115  }
   6.116 +void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
   6.117 +  if (!TraceMethodHandles)  return;
   6.118 +  BLOCK_COMMENT("trace_method_handle {");
   6.119 +  // save: Gargs, O5_savedSP
   6.120 +  __ save_frame(16);
   6.121 +  __ set((intptr_t) adaptername, O0);
   6.122 +  __ mov(G3_method_handle, O1);
   6.123 +  __ mov(G3_method_handle, L3);
   6.124 +  __ mov(Gargs, L4);
   6.125 +  __ mov(G5_method_type, L5);
   6.126 +  __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
   6.127 +
   6.128 +  __ mov(L3, G3_method_handle);
   6.129 +  __ mov(L4, Gargs);
   6.130 +  __ mov(L5, G5_method_type);
   6.131 +  __ restore();
   6.132 +  BLOCK_COMMENT("} trace_method_handle");
   6.133 +}
   6.134  #endif // PRODUCT
   6.135  
   6.136  // which conversion op types are implemented here?
   6.137 @@ -348,18 +367,8 @@
   6.138    }
   6.139  
   6.140    address interp_entry = __ pc();
   6.141 -  if (UseCompressedOops)  __ unimplemented("UseCompressedOops");
   6.142  
   6.143 -#ifndef PRODUCT
   6.144 -  if (TraceMethodHandles) {
   6.145 -    // save: Gargs, O5_savedSP
   6.146 -    __ save(SP, -16*wordSize, SP);
   6.147 -    __ set((intptr_t) entry_name(ek), O0);
   6.148 -    __ mov(G3_method_handle, O1);
   6.149 -    __ call_VM_leaf(Lscratch, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
   6.150 -    __ restore(SP, 16*wordSize, SP);
   6.151 -  }
   6.152 -#endif // PRODUCT
   6.153 +  trace_method_handle(_masm, entry_name(ek));
   6.154  
   6.155    switch ((int) ek) {
   6.156    case _raise_exception:
   6.157 @@ -413,7 +422,7 @@
   6.158    case _invokestatic_mh:
   6.159    case _invokespecial_mh:
   6.160      {
   6.161 -      __ ld_ptr(G3_mh_vmtarget, G5_method);  // target is a methodOop
   6.162 +      __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
   6.163        __ verify_oop(G5_method);
   6.164        // Same as TemplateTable::invokestatic or invokespecial,
   6.165        // minus the CP setup and profiling:
   6.166 @@ -468,7 +477,7 @@
   6.167        // minus the CP setup and profiling:
   6.168        __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
   6.169        Register O1_intf  = O1_scratch;
   6.170 -      __ ld_ptr(G3_mh_vmtarget, O1_intf);
   6.171 +      __ load_heap_oop(G3_mh_vmtarget, O1_intf);
   6.172        __ ldsw(G3_dmh_vmindex, G5_index);
   6.173        __ ld_ptr(__ argument_address(O0_argslot, -1), G3_method_handle);
   6.174        __ null_check(G3_method_handle, oopDesc::klass_offset_in_bytes());
   6.175 @@ -523,7 +532,7 @@
   6.176        insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, O0_argslot, O1_scratch, O2_scratch, G5_index);
   6.177  
   6.178        // Store bound argument into the new stack slot:
   6.179 -      __ ld_ptr(G3_bmh_argument, O1_scratch);
   6.180 +      __ load_heap_oop(G3_bmh_argument, O1_scratch);
   6.181        if (arg_type == T_OBJECT) {
   6.182          __ st_ptr(O1_scratch, Address(O0_argslot, 0));
   6.183        } else {
   6.184 @@ -541,12 +550,12 @@
   6.185        }
   6.186  
   6.187        if (direct_to_method) {
   6.188 -        __ ld_ptr(G3_mh_vmtarget, G5_method);  // target is a methodOop
   6.189 +        __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
   6.190          __ verify_oop(G5_method);
   6.191          __ jump_indirect_to(G5_method_fie, O1_scratch);
   6.192          __ delayed()->nop();
   6.193        } else {
   6.194 -        __ ld_ptr(G3_mh_vmtarget, G3_method_handle);  // target is a methodOop
   6.195 +        __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);  // target is a methodOop
   6.196          __ verify_oop(G3_method_handle);
   6.197          __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.198        }
   6.199 @@ -556,7 +565,7 @@
   6.200    case _adapter_retype_only:
   6.201    case _adapter_retype_raw:
   6.202      // Immediately jump to the next MH layer:
   6.203 -    __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.204 +    __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.205      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.206      // This is OK when all parameter types widen.
   6.207      // It is also OK when a return type narrows.
   6.208 @@ -572,8 +581,8 @@
   6.209        Address vmarg = __ argument_address(O0_argslot);
   6.210  
   6.211        // What class are we casting to?
   6.212 -      __ ld_ptr(G3_amh_argument, G5_klass);  // This is a Class object!
   6.213 -      __ ld_ptr(Address(G5_klass, java_lang_Class::klass_offset_in_bytes()), G5_klass);
   6.214 +      __ load_heap_oop(G3_amh_argument, G5_klass);  // This is a Class object!
   6.215 +      __ load_heap_oop(Address(G5_klass, java_lang_Class::klass_offset_in_bytes()), G5_klass);
   6.216  
   6.217        Label done;
   6.218        __ ld_ptr(vmarg, O1_scratch);
   6.219 @@ -590,14 +599,14 @@
   6.220  
   6.221        // If we get here, the type check failed!
   6.222        __ ldsw(G3_amh_vmargslot, O0_argslot);  // reload argslot field
   6.223 -      __ ld_ptr(G3_amh_argument, O3_scratch);  // required class
   6.224 +      __ load_heap_oop(G3_amh_argument, O3_scratch);  // required class
   6.225        __ ld_ptr(vmarg, O2_scratch);  // bad object
   6.226        __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
   6.227        __ delayed()->mov(Bytecodes::_checkcast, O1_scratch);  // who is complaining?
   6.228  
   6.229        __ bind(done);
   6.230        // Get the new MH:
   6.231 -      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.232 +      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.233        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.234      }
   6.235      break;
   6.236 @@ -676,7 +685,7 @@
   6.237        __ st(O1_scratch, vmarg);
   6.238  
   6.239        // Get the new MH:
   6.240 -      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.241 +      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.242        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.243      }
   6.244      break;
   6.245 @@ -721,7 +730,7 @@
   6.246          ShouldNotReachHere();
   6.247        }
   6.248  
   6.249 -      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.250 +      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.251        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.252      }
   6.253      break;
   6.254 @@ -851,7 +860,7 @@
   6.255          }
   6.256        }
   6.257  
   6.258 -      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.259 +      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.260        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.261      }
   6.262      break;
   6.263 @@ -895,7 +904,7 @@
   6.264        __ brx(Assembler::less, false, Assembler::pt, loop);
   6.265        __ delayed()->nop();  // FILLME
   6.266  
   6.267 -      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.268 +      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.269        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.270      }
   6.271      break;
   6.272 @@ -913,7 +922,7 @@
   6.273  
   6.274        remove_arg_slots(_masm, G5_stack_move, O0_argslot, O1_scratch, O2_scratch, O3_scratch);
   6.275  
   6.276 -      __ ld_ptr(G3_mh_vmtarget, G3_method_handle);
   6.277 +      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
   6.278        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
   6.279      }
   6.280      break;
     7.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
     7.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
     7.3 @@ -2586,6 +2586,8 @@
     7.4      __ restore();
     7.5  #endif
     7.6  
     7.7 +    assert_clean_int(O2_count, G1);     // Make sure 'count' is clean int.
     7.8 +
     7.9  #ifdef ASSERT
    7.10      // caller guarantees that the arrays really are different
    7.11      // otherwise, we would have to make conjoint checks
    7.12 @@ -2600,8 +2602,6 @@
    7.13      }
    7.14  #endif //ASSERT
    7.15  
    7.16 -    assert_clean_int(O2_count, G1);     // Make sure 'count' is clean int.
    7.17 -
    7.18      checkcast_copy_entry = __ pc();
    7.19      // caller can pass a 64-bit byte count here (from generic stub)
    7.20      BLOCK_COMMENT("Entry:");
     8.1 --- a/src/cpu/sparc/vm/stubRoutines_sparc.hpp	Wed Oct 13 11:46:46 2010 -0400
     8.2 +++ b/src/cpu/sparc/vm/stubRoutines_sparc.hpp	Fri Oct 15 15:12:04 2010 -0400
     8.3 @@ -43,7 +43,7 @@
     8.4  
     8.5  // MethodHandles adapters
     8.6  enum method_handles_platform_dependent_constants {
     8.7 -  method_handles_adapters_code_size = 12000
     8.8 +  method_handles_adapters_code_size = 15000
     8.9  };
    8.10  
    8.11  class Sparc {
     9.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Oct 13 11:46:46 2010 -0400
     9.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Oct 15 15:12:04 2010 -0400
     9.3 @@ -3273,7 +3273,7 @@
     9.4    __ sll(Rret, LogBytesPerWord, Rret);
     9.5    __ ld_ptr(Rtemp, Rret, Rret);  // get return address
     9.6  
     9.7 -  __ ld_ptr(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
     9.8 +  __ load_heap_oop(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
     9.9    __ null_check(G3_method_handle);
    9.10  
    9.11    // Adjust Rret first so Llast_SP can be same as Rret
    10.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
    10.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
    10.3 @@ -7709,9 +7709,14 @@
    10.4  void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
    10.5                                                Register temp_reg,
    10.6                                                Label& wrong_method_type) {
    10.7 -  if (UseCompressedOops)  unimplemented();  // field accesses must decode
    10.8 +  Address type_addr(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg));
    10.9    // compare method type against that of the receiver
   10.10 -  cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
   10.11 +  if (UseCompressedOops) {
   10.12 +    load_heap_oop(temp_reg, type_addr);
   10.13 +    cmpptr(mtype_reg, temp_reg);
   10.14 +  } else {
   10.15 +    cmpptr(mtype_reg, type_addr);
   10.16 +  }
   10.17    jcc(Assembler::notEqual, wrong_method_type);
   10.18  }
   10.19  
   10.20 @@ -7723,15 +7728,14 @@
   10.21  void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
   10.22                                                  Register temp_reg) {
   10.23    assert_different_registers(vmslots_reg, mh_reg, temp_reg);
   10.24 -  if (UseCompressedOops)  unimplemented();  // field accesses must decode
   10.25    // load mh.type.form.vmslots
   10.26    if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
   10.27      // hoist vmslots into every mh to avoid dependent load chain
   10.28      movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
   10.29    } else {
   10.30      Register temp2_reg = vmslots_reg;
   10.31 -    movptr(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
   10.32 -    movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
   10.33 +    load_heap_oop(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
   10.34 +    load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
   10.35      movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
   10.36    }
   10.37  }
   10.38 @@ -7745,9 +7749,8 @@
   10.39    assert(mh_reg == rcx, "caller must put MH object in rcx");
   10.40    assert_different_registers(mh_reg, temp_reg);
   10.41  
   10.42 -  if (UseCompressedOops)  unimplemented();  // field accesses must decode
   10.43 -
   10.44    // pick out the interpreted side of the handler
   10.45 +  // NOTE: vmentry is not an oop!
   10.46    movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
   10.47  
   10.48    // off we go...
   10.49 @@ -8238,6 +8241,40 @@
   10.50      movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src);
   10.51  }
   10.52  
   10.53 +void MacroAssembler::load_heap_oop(Register dst, Address src) {
   10.54 +#ifdef _LP64
   10.55 +  if (UseCompressedOops) {
   10.56 +    movl(dst, src);
   10.57 +    decode_heap_oop(dst);
   10.58 +  } else
   10.59 +#endif
   10.60 +    movptr(dst, src);
   10.61 +}
   10.62 +
   10.63 +void MacroAssembler::store_heap_oop(Address dst, Register src) {
   10.64 +#ifdef _LP64
   10.65 +  if (UseCompressedOops) {
   10.66 +    assert(!dst.uses(src), "not enough registers");
   10.67 +    encode_heap_oop(src);
   10.68 +    movl(dst, src);
   10.69 +  } else
   10.70 +#endif
   10.71 +    movptr(dst, src);
   10.72 +}
   10.73 +
   10.74 +// Used for storing NULLs.
   10.75 +void MacroAssembler::store_heap_oop_null(Address dst) {
   10.76 +#ifdef _LP64
   10.77 +  if (UseCompressedOops) {
   10.78 +    movl(dst, (int32_t)NULL_WORD);
   10.79 +  } else {
   10.80 +    movslq(dst, (int32_t)NULL_WORD);
   10.81 +  }
   10.82 +#else
   10.83 +  movl(dst, (int32_t)NULL_WORD);
   10.84 +#endif
   10.85 +}
   10.86 +
   10.87  #ifdef _LP64
   10.88  void MacroAssembler::store_klass_gap(Register dst, Register src) {
   10.89    if (UseCompressedOops) {
   10.90 @@ -8246,34 +8283,6 @@
   10.91    }
   10.92  }
   10.93  
   10.94 -void MacroAssembler::load_heap_oop(Register dst, Address src) {
   10.95 -  if (UseCompressedOops) {
   10.96 -    movl(dst, src);
   10.97 -    decode_heap_oop(dst);
   10.98 -  } else {
   10.99 -    movq(dst, src);
  10.100 -  }
  10.101 -}
  10.102 -
  10.103 -void MacroAssembler::store_heap_oop(Address dst, Register src) {
  10.104 -  if (UseCompressedOops) {
  10.105 -    assert(!dst.uses(src), "not enough registers");
  10.106 -    encode_heap_oop(src);
  10.107 -    movl(dst, src);
  10.108 -  } else {
  10.109 -    movq(dst, src);
  10.110 -  }
  10.111 -}
  10.112 -
  10.113 -// Used for storing NULLs.
  10.114 -void MacroAssembler::store_heap_oop_null(Address dst) {
  10.115 -  if (UseCompressedOops) {
  10.116 -    movl(dst, (int32_t)NULL_WORD);
  10.117 -  } else {
  10.118 -    movslq(dst, (int32_t)NULL_WORD);
  10.119 -  }
  10.120 -}
  10.121 -
  10.122  #ifdef ASSERT
  10.123  void MacroAssembler::verify_heapbase(const char* msg) {
  10.124    assert (UseCompressedOops, "should be compressed");
    11.1 --- a/src/cpu/x86/vm/assembler_x86.hpp	Wed Oct 13 11:46:46 2010 -0400
    11.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp	Fri Oct 15 15:12:04 2010 -0400
    11.3 @@ -1682,24 +1682,24 @@
    11.4    void load_klass(Register dst, Register src);
    11.5    void store_klass(Register dst, Register src);
    11.6  
    11.7 +  void load_heap_oop(Register dst, Address src);
    11.8 +  void store_heap_oop(Address dst, Register src);
    11.9 +
   11.10 +  // Used for storing NULL. All other oop constants should be
   11.11 +  // stored using routines that take a jobject.
   11.12 +  void store_heap_oop_null(Address dst);
   11.13 +
   11.14    void load_prototype_header(Register dst, Register src);
   11.15  
   11.16  #ifdef _LP64
   11.17    void store_klass_gap(Register dst, Register src);
   11.18  
   11.19 -  void load_heap_oop(Register dst, Address src);
   11.20 -  void store_heap_oop(Address dst, Register src);
   11.21 -
   11.22    // This dummy is to prevent a call to store_heap_oop from
   11.23    // converting a zero (like NULL) into a Register by giving
   11.24    // the compiler two choices it can't resolve
   11.25  
   11.26    void store_heap_oop(Address dst, void* dummy);
   11.27  
   11.28 -  // Used for storing NULL. All other oop constants should be
   11.29 -  // stored using routines that take a jobject.
   11.30 -  void store_heap_oop_null(Address dst);
   11.31 -
   11.32    void encode_heap_oop(Register r);
   11.33    void decode_heap_oop(Register r);
   11.34    void encode_heap_oop_not_null(Register r);
   11.35 @@ -1927,7 +1927,7 @@
   11.36  
   11.37    void untested()                                { stop("untested"); }
   11.38  
   11.39 -  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, sizeof(b), "unimplemented: %s", what);  stop(b); }
   11.40 +  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, 1024, "unimplemented: %s", what);  stop(b); }
   11.41  
   11.42    void should_not_reach_here()                   { stop("should not reach here"); }
   11.43  
    12.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
    12.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
    12.3 @@ -1941,8 +1941,6 @@
    12.4        __ cmpxchgptr(newval, Address(addr, 0));
    12.5      } else if (op->code() == lir_cas_int) {
    12.6        __ cmpxchgl(newval, Address(addr, 0));
    12.7 -    } else {
    12.8 -      LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0)));
    12.9      }
   12.10  #ifdef _LP64
   12.11    } else if (op->code() == lir_cas_long) {
    13.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
    13.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
    13.3 @@ -765,7 +765,7 @@
    13.4      ShouldNotReachHere();
    13.5    }
    13.6  
    13.7 -  LIR_Opr addr = new_pointer_register();
    13.8 +  LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
    13.9    LIR_Address* a;
   13.10    if(offset.result()->is_constant()) {
   13.11      a = new LIR_Address(obj.result(),
    14.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Oct 13 11:46:46 2010 -0400
    14.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Oct 15 15:12:04 2010 -0400
    14.3 @@ -123,11 +123,9 @@
    14.4    }
    14.5  
    14.6    // given the MethodType, find out where the MH argument is buried
    14.7 -  __ movptr(rdx_temp, Address(rax_mtype,
    14.8 -                              __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
    14.9 +  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
   14.10    Register rdx_vmslots = rdx_temp;
   14.11 -  __ movl(rdx_vmslots, Address(rdx_temp,
   14.12 -                               __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
   14.13 +  __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
   14.14    __ movptr(rcx_recv, __ argument_address(rdx_vmslots));
   14.15  
   14.16    trace_method_handle(_masm, "invokeExact");
   14.17 @@ -154,20 +152,18 @@
   14.18                     rcx_argslot, rbx_temp, rdx_temp);
   14.19  
   14.20    // load up an adapter from the calling type (Java weaves this)
   14.21 -  __ movptr(rdx_temp, Address(rax_mtype,
   14.22 -                              __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
   14.23 +  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
   14.24    Register rdx_adapter = rdx_temp;
   14.25 -  // movptr(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
   14.26 +  // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
   14.27    // deal with old JDK versions:
   14.28 -  __ lea(rdi_temp, Address(rdx_temp,
   14.29 -                           __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
   14.30 +  __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
   14.31    __ cmpptr(rdi_temp, rdx_temp);
   14.32    Label sorry_no_invoke_generic;
   14.33 -  __ jccb(Assembler::below, sorry_no_invoke_generic);
   14.34 +  __ jcc(Assembler::below, sorry_no_invoke_generic);
   14.35  
   14.36 -  __ movptr(rdx_adapter, Address(rdi_temp, 0));
   14.37 +  __ load_heap_oop(rdx_adapter, Address(rdi_temp, 0));
   14.38    __ testptr(rdx_adapter, rdx_adapter);
   14.39 -  __ jccb(Assembler::zero, sorry_no_invoke_generic);
   14.40 +  __ jcc(Assembler::zero, sorry_no_invoke_generic);
   14.41    __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter);
   14.42    // As a trusted first argument, pass the type being called, so the adapter knows
   14.43    // the actual types of the arguments and return values.
   14.44 @@ -431,7 +427,6 @@
   14.45    }
   14.46  
   14.47    address interp_entry = __ pc();
   14.48 -  if (UseCompressedOops)  __ unimplemented("UseCompressedOops");
   14.49  
   14.50    trace_method_handle(_masm, entry_name(ek));
   14.51  
   14.52 @@ -489,7 +484,7 @@
   14.53    case _invokespecial_mh:
   14.54      {
   14.55        Register rbx_method = rbx_temp;
   14.56 -      __ movptr(rbx_method, rcx_mh_vmtarget); // target is a methodOop
   14.57 +      __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop
   14.58        __ verify_oop(rbx_method);
   14.59        // same as TemplateTable::invokestatic or invokespecial,
   14.60        // minus the CP setup and profiling:
   14.61 @@ -546,8 +541,8 @@
   14.62        __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
   14.63        Register rdx_intf  = rdx_temp;
   14.64        Register rbx_index = rbx_temp;
   14.65 -      __ movptr(rdx_intf,  rcx_mh_vmtarget);
   14.66 -      __ movl(rbx_index,   rcx_dmh_vmindex);
   14.67 +      __ load_heap_oop(rdx_intf, rcx_mh_vmtarget);
   14.68 +      __ movl(rbx_index, rcx_dmh_vmindex);
   14.69        __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
   14.70        __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
   14.71  
   14.72 @@ -602,7 +597,7 @@
   14.73                         rax_argslot, rbx_temp, rdx_temp);
   14.74  
   14.75        // store bound argument into the new stack slot:
   14.76 -      __ movptr(rbx_temp, rcx_bmh_argument);
   14.77 +      __ load_heap_oop(rbx_temp, rcx_bmh_argument);
   14.78        Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
   14.79        if (arg_type == T_OBJECT) {
   14.80          __ movptr(Address(rax_argslot, 0), rbx_temp);
   14.81 @@ -620,11 +615,11 @@
   14.82  
   14.83        if (direct_to_method) {
   14.84          Register rbx_method = rbx_temp;
   14.85 -        __ movptr(rbx_method, rcx_mh_vmtarget);
   14.86 +        __ load_heap_oop(rbx_method, rcx_mh_vmtarget);
   14.87          __ verify_oop(rbx_method);
   14.88          __ jmp(rbx_method_fie);
   14.89        } else {
   14.90 -        __ movptr(rcx_recv, rcx_mh_vmtarget);
   14.91 +        __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
   14.92          __ verify_oop(rcx_recv);
   14.93          __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
   14.94        }
   14.95 @@ -634,7 +629,7 @@
   14.96    case _adapter_retype_only:
   14.97    case _adapter_retype_raw:
   14.98      // immediately jump to the next MH layer:
   14.99 -    __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.100 +    __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.101      __ verify_oop(rcx_recv);
  14.102      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.103      // This is OK when all parameter types widen.
  14.104 @@ -651,13 +646,13 @@
  14.105        vmarg = __ argument_address(rax_argslot);
  14.106  
  14.107        // What class are we casting to?
  14.108 -      __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
  14.109 -      __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
  14.110 +      __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
  14.111 +      __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
  14.112  
  14.113        Label done;
  14.114        __ movptr(rdx_temp, vmarg);
  14.115        __ testptr(rdx_temp, rdx_temp);
  14.116 -      __ jccb(Assembler::zero, done);         // no cast if null
  14.117 +      __ jcc(Assembler::zero, done);         // no cast if null
  14.118        __ load_klass(rdx_temp, rdx_temp);
  14.119  
  14.120        // live at this point:
  14.121 @@ -672,14 +667,15 @@
  14.122        __ movl(rax_argslot, rcx_amh_vmargslot);  // reload argslot field
  14.123        __ movptr(rdx_temp, vmarg);
  14.124  
  14.125 -      __ pushptr(rcx_amh_argument); // required class
  14.126 -      __ push(rdx_temp);            // bad object
  14.127 -      __ push((int)Bytecodes::_checkcast);  // who is complaining?
  14.128 +      __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class
  14.129 +      __ push(rbx_klass);
  14.130 +      __ push(rdx_temp);                             // bad object
  14.131 +      __ push((int)Bytecodes::_checkcast);           // who is complaining?
  14.132        __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
  14.133  
  14.134        __ bind(done);
  14.135        // get the new MH:
  14.136 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.137 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.138        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.139      }
  14.140      break;
  14.141 @@ -741,7 +737,7 @@
  14.142        assert(CONV_VMINFO_SHIFT == 0, "preshifted");
  14.143  
  14.144        // get the new MH:
  14.145 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.146 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.147        // (now we are done with the old MH)
  14.148  
  14.149        // original 32-bit vmdata word must be of this form:
  14.150 @@ -816,7 +812,7 @@
  14.151          ShouldNotReachHere();
  14.152        }
  14.153  
  14.154 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.155 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.156        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.157      }
  14.158      break;
  14.159 @@ -858,7 +854,7 @@
  14.160                           rax_argslot, rbx_temp, rdx_temp);
  14.161        }
  14.162  
  14.163 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.164 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.165        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.166      }
  14.167      break;
  14.168 @@ -969,7 +965,7 @@
  14.169          }
  14.170        }
  14.171  
  14.172 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.173 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.174        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.175      }
  14.176      break;
  14.177 @@ -1029,7 +1025,7 @@
  14.178  
  14.179        __ pop(rdi);              // restore temp
  14.180  
  14.181 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.182 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.183        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.184      }
  14.185      break;
  14.186 @@ -1052,7 +1048,7 @@
  14.187  
  14.188        __ pop(rdi);              // restore temp
  14.189  
  14.190 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.191 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.192        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.193      }
  14.194      break;
  14.195 @@ -1103,8 +1099,8 @@
  14.196  
  14.197        // Check the array type.
  14.198        Register rbx_klass = rbx_temp;
  14.199 -      __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
  14.200 -      __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
  14.201 +      __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
  14.202 +      __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
  14.203  
  14.204        Label ok_array_klass, bad_array_klass, bad_array_length;
  14.205        __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass);
  14.206 @@ -1186,7 +1182,7 @@
  14.207  
  14.208        // Arguments are spread.  Move to next method handle.
  14.209        UNPUSH_RSI_RDI;
  14.210 -      __ movptr(rcx_recv, rcx_mh_vmtarget);
  14.211 +      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
  14.212        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
  14.213  
  14.214        __ bind(bad_array_klass);
    15.1 --- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Wed Oct 13 11:46:46 2010 -0400
    15.2 +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Fri Oct 15 15:12:04 2010 -0400
    15.3 @@ -35,7 +35,7 @@
    15.4  
    15.5  // MethodHandles adapters
    15.6  enum method_handles_platform_dependent_constants {
    15.7 -  method_handles_adapters_code_size = 26000
    15.8 +  method_handles_adapters_code_size = 40000
    15.9  };
   15.10  
   15.11  class x86 {
    16.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Wed Oct 13 11:46:46 2010 -0400
    16.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Fri Oct 15 15:12:04 2010 -0400
    16.3 @@ -3111,19 +3111,22 @@
    16.4  
    16.5    // rax: CallSite object (f1)
    16.6    // rbx: unused (f2)
    16.7 +  // rcx: receiver address
    16.8    // rdx: flags (unused)
    16.9  
   16.10 +  Register rax_callsite      = rax;
   16.11 +  Register rcx_method_handle = rcx;
   16.12 +
   16.13    if (ProfileInterpreter) {
   16.14 -    Label L;
   16.15      // %%% should make a type profile for any invokedynamic that takes a ref argument
   16.16      // profile this call
   16.17      __ profile_call(rsi);
   16.18    }
   16.19  
   16.20 -  __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
   16.21 -  __ null_check(rcx);
   16.22 +  __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
   16.23 +  __ null_check(rcx_method_handle);
   16.24    __ prepare_to_jump_from_interpreted();
   16.25 -  __ jump_to_method_handle_entry(rcx, rdx);
   16.26 +  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
   16.27  }
   16.28  
   16.29  //----------------------------------------------------------------------------------------------------
    17.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Oct 13 11:46:46 2010 -0400
    17.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Fri Oct 15 15:12:04 2010 -0400
    17.3 @@ -3120,17 +3120,19 @@
    17.4    // rcx: receiver address
    17.5    // rdx: flags (unused)
    17.6  
    17.7 +  Register rax_callsite      = rax;
    17.8 +  Register rcx_method_handle = rcx;
    17.9 +
   17.10    if (ProfileInterpreter) {
   17.11 -    Label L;
   17.12      // %%% should make a type profile for any invokedynamic that takes a ref argument
   17.13      // profile this call
   17.14      __ profile_call(r13);
   17.15    }
   17.16  
   17.17 -  __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
   17.18 -  __ null_check(rcx);
   17.19 +  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
   17.20 +  __ null_check(rcx_method_handle);
   17.21    __ prepare_to_jump_from_interpreted();
   17.22 -  __ jump_to_method_handle_entry(rcx, rdx);
   17.23 +  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
   17.24  }
   17.25  
   17.26  
    18.1 --- a/src/cpu/zero/vm/interpreterRT_zero.hpp	Wed Oct 13 11:46:46 2010 -0400
    18.2 +++ b/src/cpu/zero/vm/interpreterRT_zero.hpp	Fri Oct 15 15:12:04 2010 -0400
    18.3 @@ -92,15 +92,15 @@
    18.4  
    18.5   public:
    18.6    SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer)
    18.7 -    : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()),
    18.8 +    : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->insts_end()),
    18.9        _cb(buffer) {
   18.10 -    _cb->set_code_end((address) (cif() + 1));
   18.11 +    _cb->set_insts_end((address) (cif() + 1));
   18.12    }
   18.13  
   18.14   private:
   18.15    void push(intptr_t value) {
   18.16 -    intptr_t *dst = (intptr_t *) _cb->code_end();
   18.17 -    _cb->set_code_end((address) (dst + 1));
   18.18 +    intptr_t *dst = (intptr_t *) _cb->insts_end();
   18.19 +    _cb->set_insts_end((address) (dst + 1));
   18.20      *dst = value;
   18.21    }
   18.22  };
    19.1 --- a/src/share/vm/asm/codeBuffer.hpp	Wed Oct 13 11:46:46 2010 -0400
    19.2 +++ b/src/share/vm/asm/codeBuffer.hpp	Fri Oct 15 15:12:04 2010 -0400
    19.3 @@ -168,8 +168,8 @@
    19.4    bool allocates(address pc) const  { return pc >= _start && pc <  _limit; }
    19.5    bool allocates2(address pc) const { return pc >= _start && pc <= _limit; }
    19.6  
    19.7 -  void    set_end(address pc)       { assert(allocates2(pc),""); _end = pc; }
    19.8 -  void    set_mark(address pc)      { assert(contains2(pc),"not in codeBuffer");
    19.9 +  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; }
   19.10 +  void    set_mark(address pc)      { assert(contains2(pc), "not in codeBuffer");
   19.11                                        _mark = pc; }
   19.12    void    set_mark_off(int offset)  { assert(contains2(offset+_start),"not in codeBuffer");
   19.13                                        _mark = offset + _start; }
    20.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Oct 13 11:46:46 2010 -0400
    20.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 15 15:12:04 2010 -0400
    20.3 @@ -1350,6 +1350,7 @@
    20.4      addr = ptr;
    20.5    }
    20.6    assert(addr->is_register(), "must be a register at this point");
    20.7 +  assert(addr->type() == T_OBJECT, "addr should point to an object");
    20.8  
    20.9    LIR_Opr xor_res = new_pointer_register();
   20.10    LIR_Opr xor_shift_res = new_pointer_register();
    21.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp	Wed Oct 13 11:46:46 2010 -0400
    21.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp	Fri Oct 15 15:12:04 2010 -0400
    21.3 @@ -471,7 +471,7 @@
    21.4      ciField* field = fields->at(i);
    21.5      int offset = field->offset_in_bytes();
    21.6      int size   = (field->_type == NULL) ? heapOopSize : field->size_in_bytes();
    21.7 -    assert(last_offset <= offset, "no field overlap");
    21.8 +    assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset));
    21.9      if (last_offset > (int)sizeof(oopDesc))
   21.10        assert((offset - last_offset) < BytesPerLong, "no big holes");
   21.11      // Note:  Two consecutive T_BYTE fields will be separated by wordSize-1
    22.1 --- a/src/share/vm/ci/ciTypeFlow.cpp	Wed Oct 13 11:46:46 2010 -0400
    22.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp	Fri Oct 15 15:12:04 2010 -0400
    22.3 @@ -1945,7 +1945,7 @@
    22.4    _has_irreducible_entry = false;
    22.5    _osr_bci = osr_bci;
    22.6    _failure_reason = NULL;
    22.7 -  assert(start_bci() >= 0 && start_bci() < code_size() , "correct osr_bci argument");
    22.8 +  assert(0 <= start_bci() && start_bci() < code_size() , err_msg("correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size()));
    22.9    _work_list = NULL;
   22.10  
   22.11    _ciblock_count = _methodBlocks->num_blocks();
    23.1 --- a/src/share/vm/classfile/classFileParser.cpp	Wed Oct 13 11:46:46 2010 -0400
    23.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Fri Oct 15 15:12:04 2010 -0400
    23.3 @@ -2702,13 +2702,15 @@
    23.4        // Adjust the field type from byte to an unmanaged pointer.
    23.5        assert(fac_ptr->nonstatic_byte_count > 0, "");
    23.6        fac_ptr->nonstatic_byte_count -= 1;
    23.7 -      (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
    23.8 -                                   word_sig_index);
    23.9 -      fac_ptr->nonstatic_word_count += 1;
   23.10 +
   23.11 +      (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index);
   23.12 +      assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64");
   23.13 +      if (wordSize == longSize)  fac_ptr->nonstatic_double_count += 1;
   23.14 +      else                       fac_ptr->nonstatic_word_count   += 1;
   23.15  
   23.16        FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset);
   23.17        assert(atype == NONSTATIC_BYTE, "");
   23.18 -      FieldAllocationType new_atype = NONSTATIC_WORD;
   23.19 +      FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD;
   23.20        (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype);
   23.21  
   23.22        found_vmentry = true;
    24.1 --- a/src/share/vm/code/nmethod.cpp	Wed Oct 13 11:46:46 2010 -0400
    24.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Oct 15 15:12:04 2010 -0400
    24.3 @@ -1421,7 +1421,7 @@
    24.4    }
    24.5  
    24.6  #ifdef SHARK
    24.7 -  ((SharkCompiler *) compiler())->free_compiled_method(instructions_begin());
    24.8 +  ((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
    24.9  #endif // SHARK
   24.10  
   24.11    ((CodeBlob*)(this))->flush();
    25.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Oct 13 11:46:46 2010 -0400
    25.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Oct 15 15:12:04 2010 -0400
    25.3 @@ -791,7 +791,7 @@
    25.4    int                _worker_i;
    25.5  public:
    25.6    RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) :
    25.7 -    _cl(g1->g1_rem_set()->as_HRInto_G1RemSet(), worker_i),
    25.8 +    _cl(g1->g1_rem_set(), worker_i),
    25.9      _worker_i(worker_i),
   25.10      _g1h(g1)
   25.11    { }
   25.12 @@ -890,7 +890,7 @@
   25.13      abandon_cur_alloc_region();
   25.14      abandon_gc_alloc_regions();
   25.15      assert(_cur_alloc_region == NULL, "Invariant.");
   25.16 -    g1_rem_set()->as_HRInto_G1RemSet()->cleanupHRRS();
   25.17 +    g1_rem_set()->cleanupHRRS();
   25.18      tear_down_region_lists();
   25.19      set_used_regions_to_need_zero_fill();
   25.20  
   25.21 @@ -1506,15 +1506,11 @@
   25.22    }
   25.23  
   25.24    // Also create a G1 rem set.
   25.25 -  if (G1UseHRIntoRS) {
   25.26 -    if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
   25.27 -      _g1_rem_set = new HRInto_G1RemSet(this, (CardTableModRefBS*)mr_bs());
   25.28 -    } else {
   25.29 -      vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
   25.30 -      return JNI_ENOMEM;
   25.31 -    }
   25.32 +  if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
   25.33 +    _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
   25.34    } else {
   25.35 -    _g1_rem_set = new StupidG1RemSet(this);
   25.36 +    vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
   25.37 +    return JNI_ENOMEM;
   25.38    }
   25.39  
   25.40    // Carve out the G1 part of the heap.
   25.41 @@ -2706,8 +2702,7 @@
   25.42  }
   25.43  
   25.44  size_t G1CollectedHeap::cards_scanned() {
   25.45 -  HRInto_G1RemSet* g1_rset = (HRInto_G1RemSet*) g1_rem_set();
   25.46 -  return g1_rset->cardsScanned();
   25.47 +  return g1_rem_set()->cardsScanned();
   25.48  }
   25.49  
   25.50  void
   25.51 @@ -3850,6 +3845,54 @@
   25.52                 undo_waste() * HeapWordSize / K);
   25.53  }
   25.54  
   25.55 +#ifdef ASSERT
   25.56 +bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
   25.57 +  assert(ref != NULL, "invariant");
   25.58 +  assert(UseCompressedOops, "sanity");
   25.59 +  assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref));
   25.60 +  oop p = oopDesc::load_decode_heap_oop(ref);
   25.61 +  assert(_g1h->is_in_g1_reserved(p),
   25.62 +         err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
   25.63 +  return true;
   25.64 +}
   25.65 +
   25.66 +bool G1ParScanThreadState::verify_ref(oop* ref) const {
   25.67 +  assert(ref != NULL, "invariant");
   25.68 +  if (has_partial_array_mask(ref)) {
   25.69 +    // Must be in the collection set--it's already been copied.
   25.70 +    oop p = clear_partial_array_mask(ref);
   25.71 +    assert(_g1h->obj_in_cs(p),
   25.72 +           err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
   25.73 +  } else {
   25.74 +    oop p = oopDesc::load_decode_heap_oop(ref);
   25.75 +    assert(_g1h->is_in_g1_reserved(p),
   25.76 +           err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
   25.77 +  }
   25.78 +  return true;
   25.79 +}
   25.80 +
   25.81 +bool G1ParScanThreadState::verify_task(StarTask ref) const {
   25.82 +  if (ref.is_narrow()) {
   25.83 +    return verify_ref((narrowOop*) ref);
   25.84 +  } else {
   25.85 +    return verify_ref((oop*) ref);
   25.86 +  }
   25.87 +}
   25.88 +#endif // ASSERT
   25.89 +
   25.90 +void G1ParScanThreadState::trim_queue() {
   25.91 +  StarTask ref;
   25.92 +  do {
   25.93 +    // Drain the overflow stack first, so other threads can steal.
   25.94 +    while (refs()->pop_overflow(ref)) {
   25.95 +      deal_with_reference(ref);
   25.96 +    }
   25.97 +    while (refs()->pop_local(ref)) {
   25.98 +      deal_with_reference(ref);
   25.99 +    }
  25.100 +  } while (!refs()->is_empty());
  25.101 +}
  25.102 +
  25.103  G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
  25.104    _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
  25.105    _par_scan_state(par_scan_state) { }
  25.106 @@ -4052,38 +4095,39 @@
  25.107      : _g1h(g1h), _par_scan_state(par_scan_state),
  25.108        _queues(queues), _terminator(terminator) {}
  25.109  
  25.110 -  void do_void() {
  25.111 -    G1ParScanThreadState* pss = par_scan_state();
  25.112 -    while (true) {
  25.113 +  void do_void();
  25.114 +
  25.115 +private:
  25.116 +  inline bool offer_termination();
  25.117 +};
  25.118 +
  25.119 +bool G1ParEvacuateFollowersClosure::offer_termination() {
  25.120 +  G1ParScanThreadState* const pss = par_scan_state();
  25.121 +  pss->start_term_time();
  25.122 +  const bool res = terminator()->offer_termination();
  25.123 +  pss->end_term_time();
  25.124 +  return res;
  25.125 +}
  25.126 +
  25.127 +void G1ParEvacuateFollowersClosure::do_void() {
  25.128 +  StarTask stolen_task;
  25.129 +  G1ParScanThreadState* const pss = par_scan_state();
  25.130 +  pss->trim_queue();
  25.131 +
  25.132 +  do {
  25.133 +    while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) {
  25.134 +      assert(pss->verify_task(stolen_task), "sanity");
  25.135 +      if (stolen_task.is_narrow()) {
  25.136 +        pss->push_on_queue((narrowOop*) stolen_task);
  25.137 +      } else {
  25.138 +        pss->push_on_queue((oop*) stolen_task);
  25.139 +      }
  25.140        pss->trim_queue();
  25.141 -
  25.142 -      StarTask stolen_task;
  25.143 -      if (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) {
  25.144 -        // slightly paranoid tests; I'm trying to catch potential
  25.145 -        // problems before we go into push_on_queue to know where the
  25.146 -        // problem is coming from
  25.147 -        assert((oop*)stolen_task != NULL, "Error");
  25.148 -        if (stolen_task.is_narrow()) {
  25.149 -          assert(UseCompressedOops, "Error");
  25.150 -          narrowOop* p = (narrowOop*) stolen_task;
  25.151 -          assert(has_partial_array_mask(p) ||
  25.152 -                 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "Error");
  25.153 -          pss->push_on_queue(p);
  25.154 -        } else {
  25.155 -          oop* p = (oop*) stolen_task;
  25.156 -          assert(has_partial_array_mask(p) || _g1h->is_in_g1_reserved(*p), "Error");
  25.157 -          pss->push_on_queue(p);
  25.158 -        }
  25.159 -        continue;
  25.160 -      }
  25.161 -      pss->start_term_time();
  25.162 -      if (terminator()->offer_termination()) break;
  25.163 -      pss->end_term_time();
  25.164      }
  25.165 -    pss->end_term_time();
  25.166 -    pss->retire_alloc_buffers();
  25.167 -  }
  25.168 -};
  25.169 +  } while (!offer_termination());
  25.170 +
  25.171 +  pss->retire_alloc_buffers();
  25.172 +}
  25.173  
  25.174  class G1ParTask : public AbstractGangTask {
  25.175  protected:
  25.176 @@ -4182,8 +4226,7 @@
  25.177        pss.print_termination_stats(i);
  25.178      }
  25.179  
  25.180 -    assert(pss.refs_to_scan() == 0, "Task queue should be empty");
  25.181 -    assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty");
  25.182 +    assert(pss.refs()->is_empty(), "should be empty");
  25.183      double end_time_ms = os::elapsedTime() * 1000.0;
  25.184      _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms);
  25.185    }
    26.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Oct 13 11:46:46 2010 -0400
    26.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Oct 15 15:12:04 2010 -0400
    26.3 @@ -1651,49 +1651,17 @@
    26.4    size_t alloc_buffer_waste() const              { return _alloc_buffer_waste; }
    26.5    size_t undo_waste() const                      { return _undo_waste; }
    26.6  
    26.7 +#ifdef ASSERT
    26.8 +  bool verify_ref(narrowOop* ref) const;
    26.9 +  bool verify_ref(oop* ref) const;
   26.10 +  bool verify_task(StarTask ref) const;
   26.11 +#endif // ASSERT
   26.12 +
   26.13    template <class T> void push_on_queue(T* ref) {
   26.14 -    assert(ref != NULL, "invariant");
   26.15 -    assert(has_partial_array_mask(ref) ||
   26.16 -           _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(ref)), "invariant");
   26.17 -#ifdef ASSERT
   26.18 -    if (has_partial_array_mask(ref)) {
   26.19 -      oop p = clear_partial_array_mask(ref);
   26.20 -      // Verify that we point into the CS
   26.21 -      assert(_g1h->obj_in_cs(p), "Should be in CS");
   26.22 -    }
   26.23 -#endif
   26.24 +    assert(verify_ref(ref), "sanity");
   26.25      refs()->push(ref);
   26.26    }
   26.27  
   26.28 -  void pop_from_queue(StarTask& ref) {
   26.29 -    if (refs()->pop_local(ref)) {
   26.30 -      assert((oop*)ref != NULL, "pop_local() returned true");
   26.31 -      assert(UseCompressedOops || !ref.is_narrow(), "Error");
   26.32 -      assert(has_partial_array_mask((oop*)ref) ||
   26.33 -             _g1h->is_in_g1_reserved(ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)ref)
   26.34 -                                                     : oopDesc::load_decode_heap_oop((oop*)ref)),
   26.35 -              "invariant");
   26.36 -    } else {
   26.37 -      StarTask null_task;
   26.38 -      ref = null_task;
   26.39 -    }
   26.40 -  }
   26.41 -
   26.42 -  void pop_from_overflow_queue(StarTask& ref) {
   26.43 -    StarTask new_ref;
   26.44 -    refs()->pop_overflow(new_ref);
   26.45 -    assert((oop*)new_ref != NULL, "pop() from a local non-empty stack");
   26.46 -    assert(UseCompressedOops || !new_ref.is_narrow(), "Error");
   26.47 -    assert(has_partial_array_mask((oop*)new_ref) ||
   26.48 -           _g1h->is_in_g1_reserved(new_ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)new_ref)
   26.49 -                                                       : oopDesc::load_decode_heap_oop((oop*)new_ref)),
   26.50 -           "invariant");
   26.51 -    ref = new_ref;
   26.52 -  }
   26.53 -
   26.54 -  int refs_to_scan()            { return (int)refs()->size(); }
   26.55 -  int overflowed_refs_to_scan() { return (int)refs()->overflow_stack()->size(); }
   26.56 -
   26.57    template <class T> void update_rs(HeapRegion* from, T* p, int tid) {
   26.58      if (G1DeferredRSUpdate) {
   26.59        deferred_rs_update(from, p, tid);
   26.60 @@ -1818,59 +1786,15 @@
   26.61      }
   26.62    }
   26.63  
   26.64 -public:
   26.65 -  void trim_queue() {
   26.66 -    // I've replicated the loop twice, first to drain the overflow
   26.67 -    // queue, second to drain the task queue. This is better than
   26.68 -    // having a single loop, which checks both conditions and, inside
   26.69 -    // it, either pops the overflow queue or the task queue, as each
   26.70 -    // loop is tighter. Also, the decision to drain the overflow queue
   26.71 -    // first is not arbitrary, as the overflow queue is not visible
   26.72 -    // to the other workers, whereas the task queue is. So, we want to
   26.73 -    // drain the "invisible" entries first, while allowing the other
   26.74 -    // workers to potentially steal the "visible" entries.
   26.75 -
   26.76 -    while (refs_to_scan() > 0 || overflowed_refs_to_scan() > 0) {
   26.77 -      while (overflowed_refs_to_scan() > 0) {
   26.78 -        StarTask ref_to_scan;
   26.79 -        assert((oop*)ref_to_scan == NULL, "Constructed above");
   26.80 -        pop_from_overflow_queue(ref_to_scan);
   26.81 -        // We shouldn't have pushed it on the queue if it was not
   26.82 -        // pointing into the CSet.
   26.83 -        assert((oop*)ref_to_scan != NULL, "Follows from inner loop invariant");
   26.84 -        if (ref_to_scan.is_narrow()) {
   26.85 -          assert(UseCompressedOops, "Error");
   26.86 -          narrowOop* p = (narrowOop*)ref_to_scan;
   26.87 -          assert(!has_partial_array_mask(p) &&
   26.88 -                 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
   26.89 -          deal_with_reference(p);
   26.90 -        } else {
   26.91 -          oop* p = (oop*)ref_to_scan;
   26.92 -          assert((has_partial_array_mask(p) && _g1h->is_in_g1_reserved(clear_partial_array_mask(p))) ||
   26.93 -                 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
   26.94 -          deal_with_reference(p);
   26.95 -        }
   26.96 -      }
   26.97 -
   26.98 -      while (refs_to_scan() > 0) {
   26.99 -        StarTask ref_to_scan;
  26.100 -        assert((oop*)ref_to_scan == NULL, "Constructed above");
  26.101 -        pop_from_queue(ref_to_scan);
  26.102 -        if ((oop*)ref_to_scan != NULL) {
  26.103 -          if (ref_to_scan.is_narrow()) {
  26.104 -            assert(UseCompressedOops, "Error");
  26.105 -            narrowOop* p = (narrowOop*)ref_to_scan;
  26.106 -            assert(!has_partial_array_mask(p) &&
  26.107 -                    _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
  26.108 -            deal_with_reference(p);
  26.109 -          } else {
  26.110 -            oop* p = (oop*)ref_to_scan;
  26.111 -            assert((has_partial_array_mask(p) && _g1h->obj_in_cs(clear_partial_array_mask(p))) ||
  26.112 -                   _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
  26.113 -            deal_with_reference(p);
  26.114 -          }
  26.115 -        }
  26.116 -      }
  26.117 +  void deal_with_reference(StarTask ref) {
  26.118 +    assert(verify_task(ref), "sanity");
  26.119 +    if (ref.is_narrow()) {
  26.120 +      deal_with_reference((narrowOop*)ref);
  26.121 +    } else {
  26.122 +      deal_with_reference((oop*)ref);
  26.123      }
  26.124    }
  26.125 +
  26.126 +public:
  26.127 +  void trim_queue();
  26.128  };
    27.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Wed Oct 13 11:46:46 2010 -0400
    27.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Fri Oct 15 15:12:04 2010 -0400
    27.3 @@ -25,8 +25,6 @@
    27.4  class HeapRegion;
    27.5  class G1CollectedHeap;
    27.6  class G1RemSet;
    27.7 -class HRInto_G1RemSet;
    27.8 -class G1RemSet;
    27.9  class ConcurrentMark;
   27.10  class DirtyCardToOopClosure;
   27.11  class CMBitMap;
    28.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Oct 13 11:46:46 2010 -0400
    28.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Oct 15 15:12:04 2010 -0400
    28.3 @@ -97,13 +97,6 @@
    28.4    }
    28.5  };
    28.6  
    28.7 -void
    28.8 -StupidG1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
    28.9 -                                            int worker_i) {
   28.10 -  IntoCSRegionClosure rc(_g1, oc);
   28.11 -  _g1->heap_region_iterate(&rc);
   28.12 -}
   28.13 -
   28.14  class VerifyRSCleanCardOopClosure: public OopClosure {
   28.15    G1CollectedHeap* _g1;
   28.16  public:
   28.17 @@ -119,8 +112,9 @@
   28.18    }
   28.19  };
   28.20  
   28.21 -HRInto_G1RemSet::HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
   28.22 -  : G1RemSet(g1), _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
   28.23 +G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
   28.24 +  : _g1(g1), _conc_refine_cards(0),
   28.25 +    _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
   28.26      _cg1r(g1->concurrent_g1_refine()),
   28.27      _traversal_in_progress(false),
   28.28      _cset_rs_update_cl(NULL),
   28.29 @@ -134,7 +128,7 @@
   28.30    }
   28.31  }
   28.32  
   28.33 -HRInto_G1RemSet::~HRInto_G1RemSet() {
   28.34 +G1RemSet::~G1RemSet() {
   28.35    delete _seq_task;
   28.36    for (uint i = 0; i < n_workers(); i++) {
   28.37      assert(_cset_rs_update_cl[i] == NULL, "it should be");
   28.38 @@ -277,7 +271,7 @@
   28.39  //          p threads
   28.40  // Then thread t will start at region t * floor (n/p)
   28.41  
   28.42 -HeapRegion* HRInto_G1RemSet::calculateStartRegion(int worker_i) {
   28.43 +HeapRegion* G1RemSet::calculateStartRegion(int worker_i) {
   28.44    HeapRegion* result = _g1p->collection_set();
   28.45    if (ParallelGCThreads > 0) {
   28.46      size_t cs_size = _g1p->collection_set_size();
   28.47 @@ -290,7 +284,7 @@
   28.48    return result;
   28.49  }
   28.50  
   28.51 -void HRInto_G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
   28.52 +void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
   28.53    double rs_time_start = os::elapsedTime();
   28.54    HeapRegion *startRegion = calculateStartRegion(worker_i);
   28.55  
   28.56 @@ -340,7 +334,7 @@
   28.57    }
   28.58  };
   28.59  
   28.60 -void HRInto_G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
   28.61 +void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
   28.62    double start = os::elapsedTime();
   28.63    // Apply the given closure to all remaining log entries.
   28.64    RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
   28.65 @@ -439,12 +433,11 @@
   28.66    }
   28.67  };
   28.68  
   28.69 -void HRInto_G1RemSet::cleanupHRRS() {
   28.70 +void G1RemSet::cleanupHRRS() {
   28.71    HeapRegionRemSet::cleanup();
   28.72  }
   28.73  
   28.74 -void
   28.75 -HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
   28.76 +void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
   28.77                                               int worker_i) {
   28.78  #if CARD_REPEAT_HISTO
   28.79    ct_freq_update_histo_and_reset();
   28.80 @@ -508,8 +501,7 @@
   28.81    _cset_rs_update_cl[worker_i] = NULL;
   28.82  }
   28.83  
   28.84 -void HRInto_G1RemSet::
   28.85 -prepare_for_oops_into_collection_set_do() {
   28.86 +void G1RemSet::prepare_for_oops_into_collection_set_do() {
   28.87  #if G1_REM_SET_LOGGING
   28.88    PrintRSClosure cl;
   28.89    _g1->collection_set_iterate(&cl);
   28.90 @@ -581,7 +573,7 @@
   28.91      //   RSet updating,
   28.92      // * the post-write barrier shouldn't be logging updates to young
   28.93      //   regions (but there is a situation where this can happen - see
   28.94 -    //   the comment in HRInto_G1RemSet::concurrentRefineOneCard below -
   28.95 +    //   the comment in G1RemSet::concurrentRefineOneCard below -
   28.96      //   that should not be applicable here), and
   28.97      // * during actual RSet updating, the filtering of cards in young
   28.98      //   regions in HeapRegion::oops_on_card_seq_iterate_careful is
   28.99 @@ -601,7 +593,7 @@
  28.100    }
  28.101  };
  28.102  
  28.103 -void HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do() {
  28.104 +void G1RemSet::cleanup_after_oops_into_collection_set_do() {
  28.105    guarantee( _cards_scanned != NULL, "invariant" );
  28.106    _total_cards_scanned = 0;
  28.107    for (uint i = 0; i < n_workers(); ++i)
  28.108 @@ -692,12 +684,12 @@
  28.109    }
  28.110  };
  28.111  
  28.112 -void HRInto_G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
  28.113 +void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
  28.114    ScrubRSClosure scrub_cl(region_bm, card_bm);
  28.115    _g1->heap_region_iterate(&scrub_cl);
  28.116  }
  28.117  
  28.118 -void HRInto_G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
  28.119 +void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
  28.120                                  int worker_num, int claim_val) {
  28.121    ScrubRSClosure scrub_cl(region_bm, card_bm);
  28.122    _g1->heap_region_par_iterate_chunked(&scrub_cl, worker_num, claim_val);
  28.123 @@ -741,7 +733,7 @@
  28.124    virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
  28.125  };
  28.126  
  28.127 -bool HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
  28.128 +bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
  28.129                                                     bool check_for_refs_into_cset) {
  28.130    // Construct the region representing the card.
  28.131    HeapWord* start = _ct_bs->addr_for(card_ptr);
  28.132 @@ -820,7 +812,7 @@
  28.133    return trigger_cl.value();
  28.134  }
  28.135  
  28.136 -bool HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
  28.137 +bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
  28.138                                                bool check_for_refs_into_cset) {
  28.139    // If the card is no longer dirty, nothing to do.
  28.140    if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
  28.141 @@ -995,7 +987,7 @@
  28.142    }
  28.143  };
  28.144  
  28.145 -void HRInto_G1RemSet::print_summary_info() {
  28.146 +void G1RemSet::print_summary_info() {
  28.147    G1CollectedHeap* g1 = G1CollectedHeap::heap();
  28.148  
  28.149  #if CARD_REPEAT_HISTO
  28.150 @@ -1029,30 +1021,26 @@
  28.151    g1->concurrent_g1_refine()->threads_do(&p);
  28.152    gclog_or_tty->print_cr("");
  28.153  
  28.154 -  if (G1UseHRIntoRS) {
  28.155 -    HRRSStatsIter blk;
  28.156 -    g1->heap_region_iterate(&blk);
  28.157 -    gclog_or_tty->print_cr("  Total heap region rem set sizes = " SIZE_FORMAT "K."
  28.158 -                           "  Max = " SIZE_FORMAT "K.",
  28.159 -                           blk.total_mem_sz()/K, blk.max_mem_sz()/K);
  28.160 -    gclog_or_tty->print_cr("  Static structures = " SIZE_FORMAT "K,"
  28.161 -                           " free_lists = " SIZE_FORMAT "K.",
  28.162 -                           HeapRegionRemSet::static_mem_size()/K,
  28.163 -                           HeapRegionRemSet::fl_mem_size()/K);
  28.164 -    gclog_or_tty->print_cr("    %d occupied cards represented.",
  28.165 -                           blk.occupied());
  28.166 -    gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
  28.167 -                           ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
  28.168 -                           blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
  28.169 -                           (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
  28.170 -                           (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
  28.171 -    gclog_or_tty->print_cr("    Did %d coarsenings.",
  28.172 -                  HeapRegionRemSet::n_coarsenings());
  28.173 -
  28.174 -  }
  28.175 +  HRRSStatsIter blk;
  28.176 +  g1->heap_region_iterate(&blk);
  28.177 +  gclog_or_tty->print_cr("  Total heap region rem set sizes = " SIZE_FORMAT "K."
  28.178 +                         "  Max = " SIZE_FORMAT "K.",
  28.179 +                         blk.total_mem_sz()/K, blk.max_mem_sz()/K);
  28.180 +  gclog_or_tty->print_cr("  Static structures = " SIZE_FORMAT "K,"
  28.181 +                         " free_lists = " SIZE_FORMAT "K.",
  28.182 +                         HeapRegionRemSet::static_mem_size()/K,
  28.183 +                         HeapRegionRemSet::fl_mem_size()/K);
  28.184 +  gclog_or_tty->print_cr("    %d occupied cards represented.",
  28.185 +                         blk.occupied());
  28.186 +  gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
  28.187 +                         ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
  28.188 +                         blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
  28.189 +                         (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
  28.190 +                         (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
  28.191 +  gclog_or_tty->print_cr("    Did %d coarsenings.", HeapRegionRemSet::n_coarsenings());
  28.192  }
  28.193  
  28.194 -void HRInto_G1RemSet::prepare_for_verify() {
  28.195 +void G1RemSet::prepare_for_verify() {
  28.196    if (G1HRRSFlushLogBuffersOnVerify &&
  28.197        (VerifyBeforeGC || VerifyAfterGC)
  28.198        &&  !_g1->full_collection()) {
    29.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Oct 13 11:46:46 2010 -0400
    29.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Oct 15 15:12:04 2010 -0400
    29.3 @@ -27,107 +27,18 @@
    29.4  
    29.5  class G1CollectedHeap;
    29.6  class CardTableModRefBarrierSet;
    29.7 -class HRInto_G1RemSet;
    29.8  class ConcurrentG1Refine;
    29.9  
   29.10 +// A G1RemSet in which each heap region has a rem set that records the
   29.11 +// external heap references into it.  Uses a mod ref bs to track updates,
   29.12 +// so that they can be used to update the individual region remsets.
   29.13 +
   29.14  class G1RemSet: public CHeapObj {
   29.15  protected:
   29.16    G1CollectedHeap* _g1;
   29.17    unsigned _conc_refine_cards;
   29.18    size_t n_workers();
   29.19  
   29.20 -public:
   29.21 -  G1RemSet(G1CollectedHeap* g1) :
   29.22 -    _g1(g1), _conc_refine_cards(0)
   29.23 -  {}
   29.24 -
   29.25 -  // Invoke "blk->do_oop" on all pointers into the CS in object in regions
   29.26 -  // outside the CS (having invoked "blk->set_region" to set the "from"
   29.27 -  // region correctly beforehand.) The "worker_i" param is for the
   29.28 -  // parallel case where the number of the worker thread calling this
   29.29 -  // function can be helpful in partitioning the work to be done. It
   29.30 -  // should be the same as the "i" passed to the calling thread's
   29.31 -  // work(i) function. In the sequential case this param will be ingored.
   29.32 -  virtual void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
   29.33 -                                           int worker_i) = 0;
   29.34 -
   29.35 -  // Prepare for and cleanup after an oops_into_collection_set_do
   29.36 -  // call.  Must call each of these once before and after (in sequential
   29.37 -  // code) any threads call oops into collection set do.  (This offers an
   29.38 -  // opportunity to sequential setup and teardown of structures needed by a
   29.39 -  // parallel iteration over the CS's RS.)
   29.40 -  virtual void prepare_for_oops_into_collection_set_do() = 0;
   29.41 -  virtual void cleanup_after_oops_into_collection_set_do() = 0;
   29.42 -
   29.43 -  // If "this" is of the given subtype, return "this", else "NULL".
   29.44 -  virtual HRInto_G1RemSet* as_HRInto_G1RemSet() { return NULL; }
   29.45 -
   29.46 -  // Record, if necessary, the fact that *p (where "p" is in region "from",
   29.47 -  // and is, a fortiori, required to be non-NULL) has changed to its new value.
   29.48 -  virtual void write_ref(HeapRegion* from, oop* p) = 0;
   29.49 -  virtual void write_ref(HeapRegion* from, narrowOop* p) = 0;
   29.50 -  virtual void par_write_ref(HeapRegion* from, oop* p, int tid) = 0;
   29.51 -  virtual void par_write_ref(HeapRegion* from, narrowOop* p, int tid) = 0;
   29.52 -
   29.53 -  // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
   29.54 -  // or card, respectively, such that a region or card with a corresponding
   29.55 -  // 0 bit contains no part of any live object.  Eliminates any remembered
   29.56 -  // set entries that correspond to dead heap ranges.
   29.57 -  virtual void scrub(BitMap* region_bm, BitMap* card_bm) = 0;
   29.58 -  // Like the above, but assumes is called in parallel: "worker_num" is the
   29.59 -  // parallel thread id of the current thread, and "claim_val" is the
   29.60 -  // value that should be used to claim heap regions.
   29.61 -  virtual void scrub_par(BitMap* region_bm, BitMap* card_bm,
   29.62 -                         int worker_num, int claim_val) = 0;
   29.63 -
   29.64 -  // Refine the card corresponding to "card_ptr".  If "sts" is non-NULL,
   29.65 -  // join and leave around parts that must be atomic wrt GC.  (NULL means
   29.66 -  // being done at a safepoint.)
   29.67 -  // With some implementations of this routine, when check_for_refs_into_cset
   29.68 -  // is true, a true result may be returned if the given card contains oops
   29.69 -  // that have references into the current collection set.
   29.70 -  virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
   29.71 -                                       bool check_for_refs_into_cset) {
   29.72 -    return false;
   29.73 -  }
   29.74 -
   29.75 -  // Print any relevant summary info.
   29.76 -  virtual void print_summary_info() {}
   29.77 -
   29.78 -  // Prepare remebered set for verification.
   29.79 -  virtual void prepare_for_verify() {};
   29.80 -};
   29.81 -
   29.82 -
   29.83 -// The simplest possible G1RemSet: iterates over all objects in non-CS
   29.84 -// regions, searching for pointers into the CS.
   29.85 -class StupidG1RemSet: public G1RemSet {
   29.86 -public:
   29.87 -  StupidG1RemSet(G1CollectedHeap* g1) : G1RemSet(g1) {}
   29.88 -
   29.89 -  void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
   29.90 -                                   int worker_i);
   29.91 -
   29.92 -  void prepare_for_oops_into_collection_set_do() {}
   29.93 -  void cleanup_after_oops_into_collection_set_do() {}
   29.94 -
   29.95 -  // Nothing is necessary in the version below.
   29.96 -  void write_ref(HeapRegion* from, oop* p) {}
   29.97 -  void write_ref(HeapRegion* from, narrowOop* p) {}
   29.98 -  void par_write_ref(HeapRegion* from, oop* p, int tid) {}
   29.99 -  void par_write_ref(HeapRegion* from, narrowOop* p, int tid) {}
  29.100 -
  29.101 -  void scrub(BitMap* region_bm, BitMap* card_bm) {}
  29.102 -  void scrub_par(BitMap* region_bm, BitMap* card_bm,
  29.103 -                 int worker_num, int claim_val) {}
  29.104 -
  29.105 -};
  29.106 -
  29.107 -// A G1RemSet in which each heap region has a rem set that records the
  29.108 -// external heap references into it.  Uses a mod ref bs to track updates,
  29.109 -// so that they can be used to update the individual region remsets.
  29.110 -
  29.111 -class HRInto_G1RemSet: public G1RemSet {
  29.112  protected:
  29.113    enum SomePrivateConstants {
  29.114      UpdateRStoMergeSync  = 0,
  29.115 @@ -175,28 +86,32 @@
  29.116    // scanned.
  29.117    void cleanupHRRS();
  29.118  
  29.119 -  HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
  29.120 -  ~HRInto_G1RemSet();
  29.121 +  G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
  29.122 +  ~G1RemSet();
  29.123  
  29.124 +  // Invoke "blk->do_oop" on all pointers into the CS in objects in regions
  29.125 +  // outside the CS (having invoked "blk->set_region" to set the "from"
  29.126 +  // region correctly beforehand.) The "worker_i" param is for the
  29.127 +  // parallel case where the number of the worker thread calling this
  29.128 +  // function can be helpful in partitioning the work to be done. It
  29.129 +  // should be the same as the "i" passed to the calling thread's
  29.130 +  // work(i) function. In the sequential case this param will be ingored.
  29.131    void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
  29.132                                     int worker_i);
  29.133  
  29.134 +  // Prepare for and cleanup after an oops_into_collection_set_do
  29.135 +  // call.  Must call each of these once before and after (in sequential
  29.136 +  // code) any threads call oops_into_collection_set_do.  (This offers an
  29.137 +  // opportunity to sequential setup and teardown of structures needed by a
  29.138 +  // parallel iteration over the CS's RS.)
  29.139    void prepare_for_oops_into_collection_set_do();
  29.140    void cleanup_after_oops_into_collection_set_do();
  29.141 +
  29.142    void scanRS(OopsInHeapRegionClosure* oc, int worker_i);
  29.143 -  template <class T> void scanNewRefsRS_work(OopsInHeapRegionClosure* oc, int worker_i);
  29.144 -  void scanNewRefsRS(OopsInHeapRegionClosure* oc, int worker_i) {
  29.145 -    if (UseCompressedOops) {
  29.146 -      scanNewRefsRS_work<narrowOop>(oc, worker_i);
  29.147 -    } else {
  29.148 -      scanNewRefsRS_work<oop>(oc, worker_i);
  29.149 -    }
  29.150 -  }
  29.151    void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i);
  29.152 +
  29.153    HeapRegion* calculateStartRegion(int i);
  29.154  
  29.155 -  HRInto_G1RemSet* as_HRInto_G1RemSet() { return this; }
  29.156 -
  29.157    CardTableModRefBS* ct_bs() { return _ct_bs; }
  29.158    size_t cardsScanned() { return _total_cards_scanned; }
  29.159  
  29.160 @@ -219,17 +134,31 @@
  29.161  
  29.162    bool self_forwarded(oop obj);
  29.163  
  29.164 +  // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
  29.165 +  // or card, respectively, such that a region or card with a corresponding
  29.166 +  // 0 bit contains no part of any live object.  Eliminates any remembered
  29.167 +  // set entries that correspond to dead heap ranges.
  29.168    void scrub(BitMap* region_bm, BitMap* card_bm);
  29.169 +
  29.170 +  // Like the above, but assumes is called in parallel: "worker_num" is the
  29.171 +  // parallel thread id of the current thread, and "claim_val" is the
  29.172 +  // value that should be used to claim heap regions.
  29.173    void scrub_par(BitMap* region_bm, BitMap* card_bm,
  29.174                   int worker_num, int claim_val);
  29.175  
  29.176 -  // If check_for_refs_into_cset is true then a true result is returned
  29.177 -  // if the card contains oops that have references into the current
  29.178 -  // collection set.
  29.179 +  // Refine the card corresponding to "card_ptr".  If "sts" is non-NULL,
  29.180 +  // join and leave around parts that must be atomic wrt GC.  (NULL means
  29.181 +  // being done at a safepoint.)
  29.182 +  // If check_for_refs_into_cset is true, a true result is returned
  29.183 +  // if the given card contains oops that have references into the
  29.184 +  // current collection set.
  29.185    virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
  29.186                                         bool check_for_refs_into_cset);
  29.187  
  29.188 +  // Print any relevant summary info.
  29.189    virtual void print_summary_info();
  29.190 +
  29.191 +  // Prepare remembered set for verification.
  29.192    virtual void prepare_for_verify();
  29.193  };
  29.194  
  29.195 @@ -250,13 +179,13 @@
  29.196  
  29.197  class UpdateRSOopClosure: public OopClosure {
  29.198    HeapRegion* _from;
  29.199 -  HRInto_G1RemSet* _rs;
  29.200 +  G1RemSet* _rs;
  29.201    int _worker_i;
  29.202  
  29.203    template <class T> void do_oop_work(T* p);
  29.204  
  29.205  public:
  29.206 -  UpdateRSOopClosure(HRInto_G1RemSet* rs, int worker_i = 0) :
  29.207 +  UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) :
  29.208      _from(NULL), _rs(rs), _worker_i(worker_i) {
  29.209      guarantee(_rs != NULL, "Requires an HRIntoG1RemSet");
  29.210    }
    30.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Wed Oct 13 11:46:46 2010 -0400
    30.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Fri Oct 15 15:12:04 2010 -0400
    30.3 @@ -30,16 +30,18 @@
    30.4    }
    30.5  }
    30.6  
    30.7 -template <class T> inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
    30.8 +template <class T>
    30.9 +inline void G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
   30.10    par_write_ref_nv(from, p, 0);
   30.11  }
   30.12  
   30.13 -inline bool HRInto_G1RemSet::self_forwarded(oop obj) {
   30.14 +inline bool G1RemSet::self_forwarded(oop obj) {
   30.15    bool result =  (obj->is_forwarded() && (obj->forwardee()== obj));
   30.16    return result;
   30.17  }
   30.18  
   30.19 -template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
   30.20 +template <class T>
   30.21 +inline void G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
   30.22    oop obj = oopDesc::load_decode_heap_oop(p);
   30.23  #ifdef ASSERT
   30.24    // can't do because of races
   30.25 @@ -77,7 +79,7 @@
   30.26        // Deferred updates to the CSet are either discarded (in the normal case),
   30.27        // or processed (if an evacuation failure occurs) at the end
   30.28        // of the collection.
   30.29 -      // See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do().
   30.30 +      // See G1RemSet::cleanup_after_oops_into_collection_set_do().
   30.31      } else {
   30.32  #if G1_REM_SET_LOGGING
   30.33        gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
   30.34 @@ -91,12 +93,14 @@
   30.35    }
   30.36  }
   30.37  
   30.38 -template <class T> inline void UpdateRSOopClosure::do_oop_work(T* p) {
   30.39 +template <class T>
   30.40 +inline void UpdateRSOopClosure::do_oop_work(T* p) {
   30.41    assert(_from != NULL, "from region must be non-NULL");
   30.42    _rs->par_write_ref(_from, p, _worker_i);
   30.43  }
   30.44  
   30.45 -template <class T> inline void UpdateRSetImmediate::do_oop_work(T* p) {
   30.46 +template <class T>
   30.47 +inline void UpdateRSetImmediate::do_oop_work(T* p) {
   30.48    assert(_from->is_in_reserved(p), "paranoia");
   30.49    T heap_oop = oopDesc::load_heap_oop(p);
   30.50    if (!oopDesc::is_null(heap_oop) && !_from->is_survivor()) {
    31.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Oct 13 11:46:46 2010 -0400
    31.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Oct 15 15:12:04 2010 -0400
    31.3 @@ -40,9 +40,6 @@
    31.4    develop(intx, G1PolicyVerbose, 0,                                         \
    31.5            "The verbosity level on G1 policy decisions")                     \
    31.6                                                                              \
    31.7 -  develop(bool, G1UseHRIntoRS, true,                                        \
    31.8 -          "Determines whether the 'advanced' HR Into rem set is used.")     \
    31.9 -                                                                            \
   31.10    develop(intx, G1MarkingVerboseLevel, 0,                                   \
   31.11            "Level (0-4) of verboseness of the marking code")                 \
   31.12                                                                              \
    32.1 --- a/src/share/vm/gc_implementation/includeDB_gc_g1	Wed Oct 13 11:46:46 2010 -0400
    32.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_g1	Fri Oct 15 15:12:04 2010 -0400
    32.3 @@ -310,10 +310,16 @@
    32.4  
    32.5  heapRegionSeq.inline.hpp                heapRegionSeq.hpp
    32.6  
    32.7 +instanceKlass.cpp                       g1RemSet.inline.hpp
    32.8 +
    32.9 +instanceRefKlass.cpp                    g1RemSet.inline.hpp
   32.10 +
   32.11  klass.hpp				g1OopClosures.hpp
   32.12  
   32.13  memoryService.cpp                       g1MemoryPool.hpp
   32.14  
   32.15 +objArrayKlass.cpp                       g1RemSet.inline.hpp
   32.16 +
   32.17  ptrQueue.cpp                            allocation.hpp
   32.18  ptrQueue.cpp                            allocation.inline.hpp
   32.19  ptrQueue.cpp                            mutex.hpp
    33.1 --- a/src/share/vm/oops/methodOop.cpp	Wed Oct 13 11:46:46 2010 -0400
    33.2 +++ b/src/share/vm/oops/methodOop.cpp	Fri Oct 15 15:12:04 2010 -0400
    33.3 @@ -758,7 +758,7 @@
    33.4  
    33.5    OrderAccess::storestore();
    33.6  #ifdef SHARK
    33.7 -  mh->_from_interpreted_entry = code->instructions_begin();
    33.8 +  mh->_from_interpreted_entry = code->insts_begin();
    33.9  #else
   33.10    mh->_from_compiled_entry = code->verified_entry_point();
   33.11    OrderAccess::storestore();
    34.1 --- a/src/share/vm/oops/oop.inline.hpp	Wed Oct 13 11:46:46 2010 -0400
    34.2 +++ b/src/share/vm/oops/oop.inline.hpp	Fri Oct 15 15:12:04 2010 -0400
    34.3 @@ -173,7 +173,7 @@
    34.4    address base = Universe::narrow_oop_base();
    34.5    int    shift = Universe::narrow_oop_shift();
    34.6    oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
    34.7 -  assert(check_obj_alignment(result), "Address not aligned");
    34.8 +  assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
    34.9    return result;
   34.10  }
   34.11  
    35.1 --- a/src/share/vm/opto/library_call.cpp	Wed Oct 13 11:46:46 2010 -0400
    35.2 +++ b/src/share/vm/opto/library_call.cpp	Fri Oct 15 15:12:04 2010 -0400
    35.3 @@ -4761,7 +4761,7 @@
    35.4        Node* cv = generate_checkcast_arraycopy(adr_type,
    35.5                                                dest_elem_klass,
    35.6                                                src, src_offset, dest, dest_offset,
    35.7 -                                              copy_length);
    35.8 +                                              ConvI2X(copy_length));
    35.9        if (cv == NULL)  cv = intcon(-1);  // failure (no stub available)
   35.10        checked_control = control();
   35.11        checked_i_o     = i_o();
   35.12 @@ -5206,7 +5206,7 @@
   35.13    int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc);
   35.14    Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
   35.15    Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
   35.16 -  Node* check_offset = _gvn.transform(n3);
   35.17 +  Node* check_offset = ConvI2X(_gvn.transform(n3));
   35.18    Node* check_value  = dest_elem_klass;
   35.19  
   35.20    Node* src_start  = array_element_address(src,  src_offset,  T_OBJECT);
    36.1 --- a/src/share/vm/opto/loopTransform.cpp	Wed Oct 13 11:46:46 2010 -0400
    36.2 +++ b/src/share/vm/opto/loopTransform.cpp	Fri Oct 15 15:12:04 2010 -0400
    36.3 @@ -2684,7 +2684,14 @@
    36.4                                                        fill_name, TypeAryPtr::get_array_body_type(t));
    36.5    call->init_req(TypeFunc::Parms+0, from);
    36.6    call->init_req(TypeFunc::Parms+1, store_value);
    36.7 +#ifdef _LP64
    36.8 +  len = new (C, 2) ConvI2LNode(len);
    36.9 +  _igvn.register_new_node_with_optimizer(len);
   36.10 +#endif
   36.11    call->init_req(TypeFunc::Parms+2, len);
   36.12 +#ifdef _LP64
   36.13 +  call->init_req(TypeFunc::Parms+3, C->top());
   36.14 +#endif
   36.15    call->init_req( TypeFunc::Control, head->init_control());
   36.16    call->init_req( TypeFunc::I_O    , C->top() )        ;   // does no i/o
   36.17    call->init_req( TypeFunc::Memory ,  mem_phi->in(LoopNode::EntryControl) );
    37.1 --- a/src/share/vm/opto/runtime.cpp	Wed Oct 13 11:46:46 2010 -0400
    37.2 +++ b/src/share/vm/opto/runtime.cpp	Fri Oct 15 15:12:04 2010 -0400
    37.3 @@ -646,12 +646,14 @@
    37.4  
    37.5  
    37.6  const TypeFunc* OptoRuntime::array_fill_Type() {
    37.7 -  // create input type (domain)
    37.8 -  const Type** fields = TypeTuple::fields(3);
    37.9 -  fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
   37.10 -  fields[TypeFunc::Parms+1] = TypeInt::INT;
   37.11 -  fields[TypeFunc::Parms+2] = TypeInt::INT;
   37.12 -  const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 3, fields);
   37.13 +  // create input type (domain): pointer, int, size_t
   37.14 +  const Type** fields = TypeTuple::fields(3 LP64_ONLY( + 1));
   37.15 +  int argp = TypeFunc::Parms;
   37.16 +  fields[argp++] = TypePtr::NOTNULL;
   37.17 +  fields[argp++] = TypeInt::INT;
   37.18 +  fields[argp++] = TypeX_X;               // size in whatevers (size_t)
   37.19 +  LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
   37.20 +  const TypeTuple *domain = TypeTuple::make(argp, fields);
   37.21  
   37.22    // create result type
   37.23    fields = TypeTuple::fields(1);
    38.1 --- a/src/share/vm/prims/methodHandles.cpp	Wed Oct 13 11:46:46 2010 -0400
    38.2 +++ b/src/share/vm/prims/methodHandles.cpp	Fri Oct 15 15:12:04 2010 -0400
    38.3 @@ -1568,7 +1568,7 @@
    38.4      if (ptype != T_INT) {
    38.5        int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
    38.6        jint value = argument->int_field(value_offset);
    38.7 -      int vminfo = adapter_subword_vminfo(ptype);
    38.8 +      int vminfo = adapter_unbox_subword_vminfo(ptype);
    38.9        jint subword = truncate_subword_from_vminfo(value, vminfo);
   38.10        if (value != subword) {
   38.11          err = "bound subword value does not fit into the subword type";
   38.12 @@ -2018,12 +2018,12 @@
   38.13          assert(src == T_INT || is_subword_type(src), "source is not float");
   38.14          // Subword-related cases are int -> {boolean,byte,char,short}.
   38.15          ek_opt = _adapter_opt_i2i;
   38.16 -        vminfo = adapter_subword_vminfo(dest);
   38.17 +        vminfo = adapter_prim_to_prim_subword_vminfo(dest);
   38.18          break;
   38.19        case 2 *4+ 1:
   38.20          if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
   38.21            ek_opt = _adapter_opt_l2i;
   38.22 -          vminfo = adapter_subword_vminfo(dest);
   38.23 +          vminfo = adapter_prim_to_prim_subword_vminfo(dest);
   38.24          } else if (src == T_DOUBLE && dest == T_FLOAT) {
   38.25            ek_opt = _adapter_opt_d2f;
   38.26          } else {
   38.27 @@ -2051,7 +2051,7 @@
   38.28        switch (type2size[dest]) {
   38.29        case 1:
   38.30          ek_opt = _adapter_opt_unboxi;
   38.31 -        vminfo = adapter_subword_vminfo(dest);
   38.32 +        vminfo = adapter_unbox_subword_vminfo(dest);
   38.33          break;
   38.34        case 2:
   38.35          ek_opt = _adapter_opt_unboxl;
    39.1 --- a/src/share/vm/prims/methodHandles.hpp	Wed Oct 13 11:46:46 2010 -0400
    39.2 +++ b/src/share/vm/prims/methodHandles.hpp	Fri Oct 15 15:12:04 2010 -0400
    39.3 @@ -226,11 +226,20 @@
    39.4    }
    39.5  
    39.6    enum { CONV_VMINFO_SIGN_FLAG = 0x80 };
    39.7 -  static int adapter_subword_vminfo(BasicType dest) {
    39.8 -    if (dest == T_BOOLEAN) return (BitsPerInt -  1);
    39.9 -    if (dest == T_CHAR)    return (BitsPerInt - 16);
   39.10 -    if (dest == T_BYTE)    return (BitsPerInt -  8) | CONV_VMINFO_SIGN_FLAG;
   39.11 -    if (dest == T_SHORT)   return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG;
   39.12 +  // Shift values for prim-to-prim conversions.
   39.13 +  static int adapter_prim_to_prim_subword_vminfo(BasicType dest) {
   39.14 +    if (dest == T_BOOLEAN) return (BitsPerInt - 1);  // boolean is 1 bit
   39.15 +    if (dest == T_CHAR)    return (BitsPerInt - BitsPerShort);
   39.16 +    if (dest == T_BYTE)    return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG;
   39.17 +    if (dest == T_SHORT)   return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG;
   39.18 +    return 0;                   // case T_INT
   39.19 +  }
   39.20 +  // Shift values for unboxing a primitive.
   39.21 +  static int adapter_unbox_subword_vminfo(BasicType dest) {
   39.22 +    if (dest == T_BOOLEAN) return (BitsPerInt - BitsPerByte );  // implemented as 1 byte
   39.23 +    if (dest == T_CHAR)    return (BitsPerInt - BitsPerShort);
   39.24 +    if (dest == T_BYTE)    return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG;
   39.25 +    if (dest == T_SHORT)   return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG;
   39.26      return 0;                   // case T_INT
   39.27    }
   39.28    // Here is the transformation the i2i adapter must perform:
    40.1 --- a/src/share/vm/shark/sharkCompiler.hpp	Wed Oct 13 11:46:46 2010 -0400
    40.2 +++ b/src/share/vm/shark/sharkCompiler.hpp	Fri Oct 15 15:12:04 2010 -0400
    40.3 @@ -103,8 +103,7 @@
    40.4    // Global access
    40.5   public:
    40.6    static SharkCompiler* compiler() {
    40.7 -    AbstractCompiler *compiler =
    40.8 -      CompileBroker::compiler(CompLevel_fast_compile);
    40.9 +    AbstractCompiler *compiler = CompileBroker::compiler(CompLevel_simple);
   40.10      assert(compiler->is_shark() && compiler->is_initialized(), "should be");
   40.11      return (SharkCompiler *) compiler;
   40.12    }
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/test/compiler/6987555/Test6987555.java	Fri Oct 15 15:12:04 2010 -0400
    41.3 @@ -0,0 +1,177 @@
    41.4 +/*
    41.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    41.7 + *
    41.8 + * This code is free software; you can redistribute it and/or modify it
    41.9 + * under the terms of the GNU General Public License version 2 only, as
   41.10 + * published by the Free Software Foundation.
   41.11 + *
   41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   41.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   41.15 + * version 2 for more details (a copy is included in the LICENSE file that
   41.16 + * accompanied this code).
   41.17 + *
   41.18 + * You should have received a copy of the GNU General Public License version
   41.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   41.21 + *
   41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   41.23 + * or visit www.oracle.com if you need additional information or have any
   41.24 + * questions.
   41.25 + *
   41.26 + */
   41.27 +
   41.28 +/**
   41.29 + * @test
   41.30 + * @bug 6987555
   41.31 + * @summary JSR 292 unboxing to a boolean value fails on big-endian SPARC
   41.32 + *
   41.33 + * @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555
   41.34 + */
   41.35 +
   41.36 +import java.dyn.*;
   41.37 +
   41.38 +public class Test6987555 {
   41.39 +    private static final Class   CLASS = Test6987555.class;
   41.40 +    private static final String  NAME  = "foo";
   41.41 +    private static final boolean DEBUG = false;
   41.42 +
   41.43 +    public static void main(String[] args) throws Throwable {
   41.44 +        testboolean();
   41.45 +        testbyte();
   41.46 +        testchar();
   41.47 +        testshort();
   41.48 +        testint();
   41.49 +    }
   41.50 +
   41.51 +    // boolean
   41.52 +    static void testboolean() throws Throwable {
   41.53 +        doboolean(false);
   41.54 +        doboolean(true);
   41.55 +    }
   41.56 +    static void doboolean(boolean x) throws Throwable {
   41.57 +        if (DEBUG)  System.out.println("boolean=" + x);
   41.58 +        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(boolean.class, boolean.class));
   41.59 +        MethodHandle mh2 = mh1.asType(MethodType.methodType(boolean.class, Boolean.class));
   41.60 +        boolean a = mh1.<boolean>invokeExact(x);
   41.61 +        boolean b = mh2.<boolean>invokeExact(Boolean.valueOf(x));
   41.62 +        assert a == b : a + " != " + b;
   41.63 +    }
   41.64 +
   41.65 +    // byte
   41.66 +    static void testbyte() throws Throwable {
   41.67 +        byte[] a = new byte[] {
   41.68 +            Byte.MIN_VALUE,
   41.69 +            Byte.MIN_VALUE + 1,
   41.70 +            -0x0F,
   41.71 +            -1,
   41.72 +            0,
   41.73 +            1,
   41.74 +            0x0F,
   41.75 +            Byte.MAX_VALUE - 1,
   41.76 +            Byte.MAX_VALUE
   41.77 +        };
   41.78 +        for (int i = 0; i < a.length; i++) {
   41.79 +            dobyte(a[i]);
   41.80 +        }
   41.81 +    }
   41.82 +    static void dobyte(byte x) throws Throwable {
   41.83 +        if (DEBUG)  System.out.println("byte=" + x);
   41.84 +        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(byte.class, byte.class));
   41.85 +        MethodHandle mh2 = mh1.asType(MethodType.methodType(byte.class, Byte.class));
   41.86 +        byte a = mh1.<byte>invokeExact(x);
   41.87 +        byte b = mh2.<byte>invokeExact(Byte.valueOf(x));
   41.88 +        assert a == b : a + " != " + b;
   41.89 +    }
   41.90 +
   41.91 +    // char
   41.92 +    static void testchar() throws Throwable {
   41.93 +        char[] a = new char[] {
   41.94 +            Character.MIN_VALUE,
   41.95 +            Character.MIN_VALUE + 1,
   41.96 +            0x000F,
   41.97 +            0x00FF,
   41.98 +            0x0FFF,
   41.99 +            Character.MAX_VALUE - 1,
  41.100 +            Character.MAX_VALUE
  41.101 +        };
  41.102 +        for (int i = 0; i < a.length; i++) {
  41.103 +            dochar(a[i]);
  41.104 +        }
  41.105 +    }
  41.106 +    static void dochar(char x) throws Throwable {
  41.107 +        if (DEBUG)  System.out.println("char=" + x);
  41.108 +        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(char.class, char.class));
  41.109 +        MethodHandle mh2 = mh1.asType(MethodType.methodType(char.class, Character.class));
  41.110 +        char a = mh1.<char>invokeExact(x);
  41.111 +        char b = mh2.<char>invokeExact(Character.valueOf(x));
  41.112 +        assert a == b : a + " != " + b;
  41.113 +    }
  41.114 +
  41.115 +    // short
  41.116 +    static void testshort() throws Throwable {
  41.117 +        short[] a = new short[] {
  41.118 +            Short.MIN_VALUE,
  41.119 +            Short.MIN_VALUE + 1,
  41.120 +            -0x0FFF,
  41.121 +            -0x00FF,
  41.122 +            -0x000F,
  41.123 +            -1,
  41.124 +            0,
  41.125 +            1,
  41.126 +            0x000F,
  41.127 +            0x00FF,
  41.128 +            0x0FFF,
  41.129 +            Short.MAX_VALUE - 1,
  41.130 +            Short.MAX_VALUE
  41.131 +        };
  41.132 +        for (int i = 0; i < a.length; i++) {
  41.133 +            doshort(a[i]);
  41.134 +        }
  41.135 +    }
  41.136 +    static void doshort(short x) throws Throwable {
  41.137 +        if (DEBUG)  System.out.println("short=" + x);
  41.138 +        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(short.class, short.class));
  41.139 +        MethodHandle mh2 = mh1.asType(MethodType.methodType(short.class, Short.class));
  41.140 +        short a = mh1.<short>invokeExact(x);
  41.141 +        short b = mh2.<short>invokeExact(Short.valueOf(x));
  41.142 +        assert a == b : a + " != " + b;
  41.143 +    }
  41.144 +
  41.145 +    // int
  41.146 +    static void testint() throws Throwable {
  41.147 +        int[] a = new int[] {
  41.148 +            Integer.MIN_VALUE,
  41.149 +            Integer.MIN_VALUE + 1,
  41.150 +            -0x00000FFF,
  41.151 +            -0x000000FF,
  41.152 +            -0x0000000F,
  41.153 +            -1,
  41.154 +            0,
  41.155 +            1,
  41.156 +            0x0000000F,
  41.157 +            0x000000FF,
  41.158 +            0x00000FFF,
  41.159 +            Integer.MAX_VALUE - 1,
  41.160 +            Integer.MAX_VALUE
  41.161 +        };
  41.162 +        for (int i = 0; i < a.length; i++) {
  41.163 +            doint(a[i]);
  41.164 +        }
  41.165 +    }
  41.166 +    static void doint(int x) throws Throwable {
  41.167 +        if (DEBUG)  System.out.println("int=" + x);
  41.168 +        MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(int.class, int.class));
  41.169 +        MethodHandle mh2 = mh1.asType(MethodType.methodType(int.class, Integer.class));
  41.170 +        int a = mh1.<int>invokeExact(x);
  41.171 +        int b = mh2.<int>invokeExact(Integer.valueOf(x));
  41.172 +        assert a == b : a + " != " + b;
  41.173 +    }
  41.174 +
  41.175 +    public static boolean foo(boolean i) { return i; }
  41.176 +    public static byte    foo(byte    i) { return i; }
  41.177 +    public static char    foo(char    i) { return i; }
  41.178 +    public static short   foo(short   i) { return i; }
  41.179 +    public static int     foo(int     i) { return i; }
  41.180 +}

mercurial