Merge

Fri, 09 Oct 2009 15:18:52 -0700

author
trims
date
Fri, 09 Oct 2009 15:18:52 -0700
changeset 1435
a1423fe86a18
parent 1419
6ddec5389232
parent 1434
708275a44e4a
child 1436
f4b900403d6e

Merge

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciObjectFactory.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/nmethod.hpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/shared/markSweep.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/shared/markSweep.hpp file | annotate | diff | comparison | revisions
src/share/vm/memory/genMarkSweep.cpp file | annotate | diff | comparison | revisions
src/share/vm/memory/iterator.cpp file | annotate | diff | comparison | revisions
src/share/vm/memory/iterator.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/idealKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/idealKit.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/sweeper.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Fri Oct 02 11:26:25 2009 -0700
     1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Fri Oct 09 15:18:52 2009 -0700
     1.3 @@ -33,6 +33,7 @@
     1.4  
     1.5  public class CodeCache {
     1.6    private static AddressField       heapField;
     1.7 +  private static AddressField       scavengeRootNMethodsField;
     1.8    private static VirtualConstructor virtualConstructor;
     1.9  
    1.10    private CodeHeap heap;
    1.11 @@ -49,6 +50,7 @@
    1.12      Type type = db.lookupType("CodeCache");
    1.13  
    1.14      heapField = type.getAddressField("_heap");
    1.15 +    scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
    1.16  
    1.17      virtualConstructor = new VirtualConstructor(db);
    1.18      // Add mappings for all possible CodeBlob subclasses
    1.19 @@ -67,6 +69,10 @@
    1.20      heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
    1.21    }
    1.22  
    1.23 +  public NMethod scavengeRootMethods() {
    1.24 +    return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
    1.25 +  }
    1.26 +
    1.27    public boolean contains(Address p) {
    1.28      return getHeap().contains(p);
    1.29    }
     2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Fri Oct 02 11:26:25 2009 -0700
     2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Fri Oct 09 15:18:52 2009 -0700
     2.3 @@ -40,7 +40,10 @@
     2.4    /** != InvocationEntryBci if this nmethod is an on-stack replacement method */
     2.5    private static CIntegerField entryBCIField;
     2.6    /** To support simple linked-list chaining of nmethods */
     2.7 -  private static AddressField  linkField;
     2.8 +  private static AddressField  osrLinkField;
     2.9 +  private static AddressField  scavengeRootLinkField;
    2.10 +  private static CIntegerField scavengeRootStateField;
    2.11 +
    2.12    /** Offsets for different nmethod parts */
    2.13    private static CIntegerField exceptionOffsetField;
    2.14    private static CIntegerField deoptOffsetField;
    2.15 @@ -87,7 +90,10 @@
    2.16      zombieInstructionSizeField  = type.getCIntegerField("_zombie_instruction_size");
    2.17      methodField                 = type.getOopField("_method");
    2.18      entryBCIField               = type.getCIntegerField("_entry_bci");
    2.19 -    linkField                   = type.getAddressField("_link");
    2.20 +    osrLinkField                = type.getAddressField("_osr_link");
    2.21 +    scavengeRootLinkField       = type.getAddressField("_scavenge_root_link");
    2.22 +    scavengeRootStateField      = type.getCIntegerField("_scavenge_root_state");
    2.23 +
    2.24      exceptionOffsetField        = type.getCIntegerField("_exception_offset");
    2.25      deoptOffsetField            = type.getCIntegerField("_deoptimize_offset");
    2.26      origPCOffsetField           = type.getCIntegerField("_orig_pc_offset");
    2.27 @@ -219,10 +225,19 @@
    2.28      return getEntryBCI();
    2.29    }
    2.30  
    2.31 -  public NMethod getLink() {
    2.32 -    return (NMethod) VMObjectFactory.newObject(NMethod.class, linkField.getValue(addr));
    2.33 +  public NMethod getOSRLink() {
    2.34 +    return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr));
    2.35    }
    2.36  
    2.37 +  public NMethod getScavengeRootLink() {
    2.38 +    return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootLinkField.getValue(addr));
    2.39 +  }
    2.40 +
    2.41 +  public int getScavengeRootState() {
    2.42 +    return (int) scavengeRootStateField.getValue(addr);
    2.43 +  }
    2.44 +
    2.45 +
    2.46    /** Tells whether frames described by this nmethod can be
    2.47        deoptimized. Note: native wrappers cannot be deoptimized. */
    2.48    public boolean canBeDeoptimized() { return isJavaMethod(); }
     3.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Oct 02 11:26:25 2009 -0700
     3.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Oct 09 15:18:52 2009 -0700
     3.3 @@ -4676,3 +4676,50 @@
     3.4      load_ptr_contents(base, G6_heapbase);
     3.5    }
     3.6  }
     3.7 +
     3.8 +// Compare char[] arrays aligned to 4 bytes.
     3.9 +void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
    3.10 +                                        Register limit, Register result,
    3.11 +                                        Register chr1, Register chr2, Label& Ldone) {
    3.12 +  Label Lvector, Lloop;
    3.13 +  assert(chr1 == result, "should be the same");
    3.14 +
    3.15 +  // Note: limit contains number of bytes (2*char_elements) != 0.
    3.16 +  andcc(limit, 0x2, chr1); // trailing character ?
    3.17 +  br(Assembler::zero, false, Assembler::pt, Lvector);
    3.18 +  delayed()->nop();
    3.19 +
    3.20 +  // compare the trailing char
    3.21 +  sub(limit, sizeof(jchar), limit);
    3.22 +  lduh(ary1, limit, chr1);
    3.23 +  lduh(ary2, limit, chr2);
    3.24 +  cmp(chr1, chr2);
    3.25 +  br(Assembler::notEqual, true, Assembler::pt, Ldone);
    3.26 +  delayed()->mov(G0, result);     // not equal
    3.27 +
    3.28 +  // only one char ?
    3.29 +  br_on_reg_cond(rc_z, true, Assembler::pn, limit, Ldone);
    3.30 +  delayed()->add(G0, 1, result); // zero-length arrays are equal
    3.31 +
    3.32 +  // word by word compare, dont't need alignment check
    3.33 +  bind(Lvector);
    3.34 +  // Shift ary1 and ary2 to the end of the arrays, negate limit
    3.35 +  add(ary1, limit, ary1);
    3.36 +  add(ary2, limit, ary2);
    3.37 +  neg(limit, limit);
    3.38 +
    3.39 +  lduw(ary1, limit, chr1);
    3.40 +  bind(Lloop);
    3.41 +  lduw(ary2, limit, chr2);
    3.42 +  cmp(chr1, chr2);
    3.43 +  br(Assembler::notEqual, true, Assembler::pt, Ldone);
    3.44 +  delayed()->mov(G0, result);     // not equal
    3.45 +  inccc(limit, 2*sizeof(jchar));
    3.46 +  // annul LDUW if branch is not taken to prevent access past end of array
    3.47 +  br(Assembler::notZero, true, Assembler::pt, Lloop);
    3.48 +  delayed()->lduw(ary1, limit, chr1); // hoisted
    3.49 +
    3.50 +  // Caller should set it:
    3.51 +  // add(G0, 1, result); // equals
    3.52 +}
    3.53 +
     4.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Oct 02 11:26:25 2009 -0700
     4.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Oct 09 15:18:52 2009 -0700
     4.3 @@ -2455,6 +2455,11 @@
     4.4    void inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2);
     4.5    void inc_counter(int*    counter_addr, Register Rtmp1, Register Rtmp2);
     4.6  
     4.7 +  // Compare char[] arrays aligned to 4 bytes.
     4.8 +  void char_arrays_equals(Register ary1, Register ary2,
     4.9 +                          Register limit, Register result,
    4.10 +                          Register chr1, Register chr2, Label& Ldone);
    4.11 +
    4.12  #undef VIRTUAL
    4.13  
    4.14  };
     5.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Oct 02 11:26:25 2009 -0700
     5.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Oct 09 15:18:52 2009 -0700
     5.3 @@ -2171,7 +2171,7 @@
     5.4      // subtype which we can't check or src is the same array as dst
     5.5      // but not necessarily exactly of type default_type.
     5.6      Label known_ok, halt;
     5.7 -    jobject2reg(op->expected_type()->encoding(), tmp);
     5.8 +    jobject2reg(op->expected_type()->constant_encoding(), tmp);
     5.9      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
    5.10      if (basic_type != T_OBJECT) {
    5.11        __ cmp(tmp, tmp2);
    5.12 @@ -2429,7 +2429,7 @@
    5.13        assert(data->is_BitData(), "need BitData for checkcast");
    5.14        Register mdo      = k_RInfo;
    5.15        Register data_val = Rtmp1;
    5.16 -      jobject2reg(md->encoding(), mdo);
    5.17 +      jobject2reg(md->constant_encoding(), mdo);
    5.18  
    5.19        int mdo_offset_bias = 0;
    5.20        if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
    5.21 @@ -2452,7 +2452,7 @@
    5.22      // patching may screw with our temporaries on sparc,
    5.23      // so let's do it before loading the class
    5.24      if (k->is_loaded()) {
    5.25 -      jobject2reg(k->encoding(), k_RInfo);
    5.26 +      jobject2reg(k->constant_encoding(), k_RInfo);
    5.27      } else {
    5.28        jobject2reg_with_patching(k_RInfo, op->info_for_patch());
    5.29      }
    5.30 @@ -2513,7 +2513,7 @@
    5.31      // patching may screw with our temporaries on sparc,
    5.32      // so let's do it before loading the class
    5.33      if (k->is_loaded()) {
    5.34 -      jobject2reg(k->encoding(), k_RInfo);
    5.35 +      jobject2reg(k->constant_encoding(), k_RInfo);
    5.36      } else {
    5.37        jobject2reg_with_patching(k_RInfo, op->info_for_patch());
    5.38      }
    5.39 @@ -2717,7 +2717,7 @@
    5.40    assert(op->tmp1()->is_single_cpu(), "tmp1 must be allocated");
    5.41    Register mdo  = op->mdo()->as_register();
    5.42    Register tmp1 = op->tmp1()->as_register();
    5.43 -  jobject2reg(md->encoding(), mdo);
    5.44 +  jobject2reg(md->constant_encoding(), mdo);
    5.45    int mdo_offset_bias = 0;
    5.46    if (!Assembler::is_simm13(md->byte_offset_of_slot(data, CounterData::count_offset()) +
    5.47                              data->size_in_bytes())) {
    5.48 @@ -2774,7 +2774,7 @@
    5.49          if (receiver == NULL) {
    5.50            Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)) -
    5.51                              mdo_offset_bias);
    5.52 -          jobject2reg(known_klass->encoding(), tmp1);
    5.53 +          jobject2reg(known_klass->constant_encoding(), tmp1);
    5.54            __ st_ptr(tmp1, recv_addr);
    5.55            Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) -
    5.56                              mdo_offset_bias);
     6.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Fri Oct 02 11:26:25 2009 -0700
     6.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Fri Oct 09 15:18:52 2009 -0700
     6.3 @@ -668,7 +668,7 @@
     6.4    __ add(obj.result(), offset.result(), addr);
     6.5  
     6.6    if (type == objectType) {  // Write-barrier needed for Object fields.
     6.7 -    pre_barrier(obj.result(), false, NULL);
     6.8 +    pre_barrier(addr, false, NULL);
     6.9    }
    6.10  
    6.11    if (type == objectType)
    6.12 @@ -896,7 +896,7 @@
    6.13    LIR_Opr len = length.result();
    6.14    BasicType elem_type = x->elt_type();
    6.15  
    6.16 -  __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
    6.17 +  __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
    6.18  
    6.19    CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
    6.20    __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
     7.1 --- a/src/cpu/sparc/vm/sparc.ad	Fri Oct 02 11:26:25 2009 -0700
     7.2 +++ b/src/cpu/sparc/vm/sparc.ad	Fri Oct 09 15:18:52 2009 -0700
     7.3 @@ -2838,63 +2838,41 @@
     7.4    %}
     7.5  
     7.6  
     7.7 -  enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
     7.8 +  enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
     7.9      Label Ldone, Lloop;
    7.10      MacroAssembler _masm(&cbuf);
    7.11  
    7.12      Register   str1_reg = reg_to_register_object($str1$$reg);
    7.13      Register   str2_reg = reg_to_register_object($str2$$reg);
    7.14 -    Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
    7.15 -    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
    7.16 +    Register   cnt1_reg = reg_to_register_object($cnt1$$reg);
    7.17 +    Register   cnt2_reg = reg_to_register_object($cnt2$$reg);
    7.18      Register result_reg = reg_to_register_object($result$$reg);
    7.19  
    7.20 -    // Get the first character position in both strings
    7.21 -    //         [8] char array, [12] offset, [16] count
    7.22 -    int  value_offset = java_lang_String:: value_offset_in_bytes();
    7.23 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
    7.24 -    int  count_offset = java_lang_String:: count_offset_in_bytes();
    7.25 -
    7.26 -    // load str1 (jchar*) base address into tmp1_reg
    7.27 -    __ load_heap_oop(str1_reg, value_offset, tmp1_reg);
    7.28 -    __ ld(str1_reg, offset_offset, result_reg);
    7.29 -    __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
    7.30 -    __   ld(str1_reg, count_offset, str1_reg); // hoisted
    7.31 -    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
    7.32 -    __   load_heap_oop(str2_reg, value_offset, tmp2_reg); // hoisted
    7.33 -    __ add(result_reg, tmp1_reg, tmp1_reg);
    7.34 -
    7.35 -    // load str2 (jchar*) base address into tmp2_reg
    7.36 -    // __ ld_ptr(str2_reg, value_offset, tmp2_reg); // hoisted
    7.37 -    __ ld(str2_reg, offset_offset, result_reg);
    7.38 -    __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
    7.39 -    __   ld(str2_reg, count_offset, str2_reg); // hoisted
    7.40 -    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
    7.41 -    __   subcc(str1_reg, str2_reg, O7); // hoisted
    7.42 -    __ add(result_reg, tmp2_reg, tmp2_reg);
    7.43 +    assert(result_reg != str1_reg &&
    7.44 +           result_reg != str2_reg &&
    7.45 +           result_reg != cnt1_reg &&
    7.46 +           result_reg != cnt2_reg ,
    7.47 +           "need different registers");
    7.48  
    7.49      // Compute the minimum of the string lengths(str1_reg) and the
    7.50      // difference of the string lengths (stack)
    7.51  
    7.52 -    // discard string base pointers, after loading up the lengths
    7.53 -    // __ ld(str1_reg, count_offset, str1_reg); // hoisted
    7.54 -    // __ ld(str2_reg, count_offset, str2_reg); // hoisted
    7.55 -
    7.56      // See if the lengths are different, and calculate min in str1_reg.
    7.57      // Stash diff in O7 in case we need it for a tie-breaker.
    7.58      Label Lskip;
    7.59 -    // __ subcc(str1_reg, str2_reg, O7); // hoisted
    7.60 -    __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
    7.61 +    __ subcc(cnt1_reg, cnt2_reg, O7);
    7.62 +    __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
    7.63      __ br(Assembler::greater, true, Assembler::pt, Lskip);
    7.64 -    // str2 is shorter, so use its count:
    7.65 -    __ delayed()->sll(str2_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
    7.66 +    // cnt2 is shorter, so use its count:
    7.67 +    __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
    7.68      __ bind(Lskip);
    7.69  
    7.70 -    // reallocate str1_reg, str2_reg, result_reg
    7.71 +    // reallocate cnt1_reg, cnt2_reg, result_reg
    7.72      // Note:  limit_reg holds the string length pre-scaled by 2
    7.73 -    Register limit_reg =   str1_reg;
    7.74 -    Register  chr2_reg =   str2_reg;
    7.75 +    Register limit_reg =   cnt1_reg;
    7.76 +    Register  chr2_reg =   cnt2_reg;
    7.77      Register  chr1_reg = result_reg;
    7.78 -    // tmp{12} are the base pointers
    7.79 +    // str{12} are the base pointers
    7.80  
    7.81      // Is the minimum length zero?
    7.82      __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
    7.83 @@ -2902,8 +2880,8 @@
    7.84      __ delayed()->mov(O7, result_reg);  // result is difference in lengths
    7.85  
    7.86      // Load first characters
    7.87 -    __ lduh(tmp1_reg, 0, chr1_reg);
    7.88 -    __ lduh(tmp2_reg, 0, chr2_reg);
    7.89 +    __ lduh(str1_reg, 0, chr1_reg);
    7.90 +    __ lduh(str2_reg, 0, chr2_reg);
    7.91  
    7.92      // Compare first characters
    7.93      __ subcc(chr1_reg, chr2_reg, chr1_reg);
    7.94 @@ -2915,7 +2893,7 @@
    7.95        // Check after comparing first character to see if strings are equivalent
    7.96        Label LSkip2;
    7.97        // Check if the strings start at same location
    7.98 -      __ cmp(tmp1_reg, tmp2_reg);
    7.99 +      __ cmp(str1_reg, str2_reg);
   7.100        __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
   7.101        __ delayed()->nop();
   7.102  
   7.103 @@ -2932,23 +2910,23 @@
   7.104      __ br(Assembler::equal, true, Assembler::pn, Ldone);
   7.105      __ delayed()->mov(O7, result_reg);  // result is difference in lengths
   7.106  
   7.107 -    // Shift tmp1_reg and tmp2_reg to the end of the arrays, negate limit
   7.108 -    __ add(tmp1_reg, limit_reg, tmp1_reg);
   7.109 -    __ add(tmp2_reg, limit_reg, tmp2_reg);
   7.110 +    // Shift str1_reg and str2_reg to the end of the arrays, negate limit
   7.111 +    __ add(str1_reg, limit_reg, str1_reg);
   7.112 +    __ add(str2_reg, limit_reg, str2_reg);
   7.113      __ neg(chr1_reg, limit_reg);  // limit = -(limit-2)
   7.114  
   7.115      // Compare the rest of the characters
   7.116 -    __ lduh(tmp1_reg, limit_reg, chr1_reg);
   7.117 +    __ lduh(str1_reg, limit_reg, chr1_reg);
   7.118      __ bind(Lloop);
   7.119 -    // __ lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
   7.120 -    __ lduh(tmp2_reg, limit_reg, chr2_reg);
   7.121 +    // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted
   7.122 +    __ lduh(str2_reg, limit_reg, chr2_reg);
   7.123      __ subcc(chr1_reg, chr2_reg, chr1_reg);
   7.124      __ br(Assembler::notZero, false, Assembler::pt, Ldone);
   7.125      assert(chr1_reg == result_reg, "result must be pre-placed");
   7.126      __ delayed()->inccc(limit_reg, sizeof(jchar));
   7.127      // annul LDUH if branch is not taken to prevent access past end of string
   7.128      __ br(Assembler::notZero, true, Assembler::pt, Lloop);
   7.129 -    __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
   7.130 +    __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
   7.131  
   7.132      // If strings are equal up to min length, return the length difference.
   7.133      __ mov(O7, result_reg);
   7.134 @@ -2957,125 +2935,80 @@
   7.135      __ bind(Ldone);
   7.136    %}
   7.137  
   7.138 -enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
   7.139 -    Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
   7.140 +enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
   7.141 +    Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
   7.142      MacroAssembler _masm(&cbuf);
   7.143  
   7.144      Register   str1_reg = reg_to_register_object($str1$$reg);
   7.145      Register   str2_reg = reg_to_register_object($str2$$reg);
   7.146 -    Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
   7.147 -    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
   7.148 +    Register    cnt_reg = reg_to_register_object($cnt$$reg);
   7.149 +    Register   tmp1_reg = O7;
   7.150      Register result_reg = reg_to_register_object($result$$reg);
   7.151  
   7.152 -    // Get the first character position in both strings
   7.153 -    //         [8] char array, [12] offset, [16] count
   7.154 -    int  value_offset = java_lang_String:: value_offset_in_bytes();
   7.155 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
   7.156 -    int  count_offset = java_lang_String:: count_offset_in_bytes();
   7.157 -
   7.158 -    // load str1 (jchar*) base address into tmp1_reg
   7.159 -    __ load_heap_oop(Address(str1_reg, value_offset), tmp1_reg);
   7.160 -    __ ld(Address(str1_reg, offset_offset), result_reg);
   7.161 -    __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
   7.162 -    __    ld(Address(str1_reg, count_offset), str1_reg); // hoisted
   7.163 -    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
   7.164 -    __    load_heap_oop(Address(str2_reg, value_offset), tmp2_reg); // hoisted
   7.165 -    __ add(result_reg, tmp1_reg, tmp1_reg);
   7.166 -
   7.167 -    // load str2 (jchar*) base address into tmp2_reg
   7.168 -    // __ ld_ptr(Address(str2_reg, value_offset), tmp2_reg); // hoisted
   7.169 -    __ ld(Address(str2_reg, offset_offset), result_reg);
   7.170 -    __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
   7.171 -    __    ld(Address(str2_reg, count_offset), str2_reg); // hoisted
   7.172 -    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
   7.173 -    __   cmp(str1_reg, str2_reg); // hoisted
   7.174 -    __ add(result_reg, tmp2_reg, tmp2_reg);
   7.175 -
   7.176 -    __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg);
   7.177 -    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.178 -    __ delayed()->mov(G0, result_reg);    // not equal
   7.179 -
   7.180 -    __ br_zero(Assembler::equal, true, Assembler::pn, str1_reg, Ldone);
   7.181 -    __ delayed()->add(G0, 1, result_reg); //equals
   7.182 -
   7.183 -    __ cmp(tmp1_reg, tmp2_reg); //same string ?
   7.184 +    assert(result_reg != str1_reg &&
   7.185 +           result_reg != str2_reg &&
   7.186 +           result_reg !=  cnt_reg &&
   7.187 +           result_reg != tmp1_reg ,
   7.188 +           "need different registers");
   7.189 +
   7.190 +    __ cmp(str1_reg, str2_reg); //same char[] ?
   7.191      __ brx(Assembler::equal, true, Assembler::pn, Ldone);
   7.192      __ delayed()->add(G0, 1, result_reg);
   7.193  
   7.194 +    __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
   7.195 +    __ delayed()->add(G0, 1, result_reg); // count == 0
   7.196 +
   7.197      //rename registers
   7.198 -    Register limit_reg =   str1_reg;
   7.199 -    Register  chr2_reg =   str2_reg;
   7.200 +    Register limit_reg =    cnt_reg;
   7.201      Register  chr1_reg = result_reg;
   7.202 -    // tmp{12} are the base pointers
   7.203 +    Register  chr2_reg =   tmp1_reg;
   7.204  
   7.205      //check for alignment and position the pointers to the ends
   7.206 -    __ or3(tmp1_reg, tmp2_reg, chr1_reg);
   7.207 -    __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
   7.208 -    __ br(Assembler::notZero, false, Assembler::pn, Lchar);
   7.209 -    __ delayed()->nop();
   7.210 -
   7.211 -    __ bind(Lword);
   7.212 -    __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2)
   7.213 -    __ andn(limit_reg, 0x3, limit_reg);
   7.214 -    __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
   7.215 -    __ delayed()->nop();
   7.216 -
   7.217 -    __ add(tmp1_reg, limit_reg, tmp1_reg);
   7.218 -    __ add(tmp2_reg, limit_reg, tmp2_reg);
   7.219 -    __ neg(limit_reg);
   7.220 -
   7.221 -    __ lduw(tmp1_reg, limit_reg, chr1_reg);
   7.222 -    __ bind(Lword_loop);
   7.223 -    __ lduw(tmp2_reg, limit_reg, chr2_reg);
   7.224 -    __ cmp(chr1_reg, chr2_reg);
   7.225 -    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.226 -    __ delayed()->mov(G0, result_reg);
   7.227 -    __ inccc(limit_reg, 2*sizeof(jchar));
   7.228 -    // annul LDUW if branch i  s not taken to prevent access past end of string
   7.229 -    __ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
   7.230 -    __ delayed()->lduw(tmp1_reg, limit_reg, chr1_reg); // hoisted
   7.231 -
   7.232 -    __ bind(Lpost_word);
   7.233 -    __ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
   7.234 -    __ delayed()->add(G0, 1, result_reg);
   7.235 -
   7.236 -    __ lduh(tmp1_reg, 0, chr1_reg);
   7.237 -    __ lduh(tmp2_reg, 0, chr2_reg);
   7.238 -    __ cmp (chr1_reg, chr2_reg);
   7.239 -    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.240 -    __ delayed()->mov(G0, result_reg);
   7.241 +    __ or3(str1_reg, str2_reg, chr1_reg);
   7.242 +    __ andcc(chr1_reg, 0x3, chr1_reg);
   7.243 +    // notZero means at least one not 4-byte aligned.
   7.244 +    // We could optimize the case when both arrays are not aligned
   7.245 +    // but it is not frequent case and it requires additional checks.
   7.246 +    __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
   7.247 +    __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
   7.248 +
   7.249 +    // Compare char[] arrays aligned to 4 bytes.
   7.250 +    __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
   7.251 +                          chr1_reg, chr2_reg, Ldone);
   7.252      __ ba(false,Ldone);
   7.253      __ delayed()->add(G0, 1, result_reg);
   7.254  
   7.255 +    // char by char compare
   7.256      __ bind(Lchar);
   7.257 -    __ add(tmp1_reg, limit_reg, tmp1_reg);
   7.258 -    __ add(tmp2_reg, limit_reg, tmp2_reg);
   7.259 +    __ add(str1_reg, limit_reg, str1_reg);
   7.260 +    __ add(str2_reg, limit_reg, str2_reg);
   7.261      __ neg(limit_reg); //negate count
   7.262  
   7.263 -    __ lduh(tmp1_reg, limit_reg, chr1_reg);
   7.264 +    __ lduh(str1_reg, limit_reg, chr1_reg);
   7.265 +    // Lchar_loop
   7.266      __ bind(Lchar_loop);
   7.267 -    __ lduh(tmp2_reg, limit_reg, chr2_reg);
   7.268 +    __ lduh(str2_reg, limit_reg, chr2_reg);
   7.269      __ cmp(chr1_reg, chr2_reg);
   7.270      __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.271      __ delayed()->mov(G0, result_reg); //not equal
   7.272      __ inccc(limit_reg, sizeof(jchar));
   7.273      // annul LDUH if branch is not taken to prevent access past end of string
   7.274 -    __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
   7.275 -    __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
   7.276 +    __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
   7.277 +    __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
   7.278  
   7.279      __ add(G0, 1, result_reg);  //equal
   7.280  
   7.281      __ bind(Ldone);
   7.282    %}
   7.283  
   7.284 -enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
   7.285 +enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{
   7.286      Label Lvector, Ldone, Lloop;
   7.287      MacroAssembler _masm(&cbuf);
   7.288  
   7.289      Register   ary1_reg = reg_to_register_object($ary1$$reg);
   7.290      Register   ary2_reg = reg_to_register_object($ary2$$reg);
   7.291      Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
   7.292 -    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
   7.293 +    Register   tmp2_reg = O7;
   7.294      Register result_reg = reg_to_register_object($result$$reg);
   7.295  
   7.296      int length_offset  = arrayOopDesc::length_offset_in_bytes();
   7.297 @@ -3101,7 +3034,7 @@
   7.298      __ br(Assembler::notEqual, true, Assembler::pn, Ldone);
   7.299      __ delayed()->mov(G0, result_reg);     // not equal
   7.300  
   7.301 -    __ br_zero(Assembler::zero, true, Assembler::pn, tmp1_reg, Ldone);
   7.302 +    __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone);
   7.303      __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
   7.304  
   7.305      // load array addresses
   7.306 @@ -3109,45 +3042,16 @@
   7.307      __ add(ary2_reg, base_offset, ary2_reg);
   7.308  
   7.309      // renaming registers
   7.310 -    Register chr1_reg  =  tmp2_reg;   // for characters in ary1
   7.311 -    Register chr2_reg  =  result_reg; // for characters in ary2
   7.312 +    Register chr1_reg  =  result_reg; // for characters in ary1
   7.313 +    Register chr2_reg  =  tmp2_reg;   // for characters in ary2
   7.314      Register limit_reg =  tmp1_reg;   // length
   7.315  
   7.316      // set byte count
   7.317      __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
   7.318 -    __ andcc(limit_reg, 0x2, chr1_reg); //trailing character ?
   7.319 -    __ br(Assembler::zero, false, Assembler::pt, Lvector);
   7.320 -    __ delayed()->nop();
   7.321 -
   7.322 -    //compare the trailing char
   7.323 -    __ sub(limit_reg, sizeof(jchar), limit_reg);
   7.324 -    __ lduh(ary1_reg, limit_reg, chr1_reg);
   7.325 -    __ lduh(ary2_reg, limit_reg, chr2_reg);
   7.326 -    __ cmp(chr1_reg, chr2_reg);
   7.327 -    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.328 -    __ delayed()->mov(G0, result_reg);     // not equal
   7.329 -
   7.330 -    // only one char ?
   7.331 -    __ br_zero(Assembler::zero, true, Assembler::pn, limit_reg, Ldone);
   7.332 -    __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
   7.333 -
   7.334 -    __ bind(Lvector);
   7.335 -    // Shift ary1_reg and ary2_reg to the end of the arrays, negate limit
   7.336 -    __ add(ary1_reg, limit_reg, ary1_reg);
   7.337 -    __ add(ary2_reg, limit_reg, ary2_reg);
   7.338 -    __ neg(limit_reg, limit_reg);
   7.339 -
   7.340 -    __ lduw(ary1_reg, limit_reg, chr1_reg);
   7.341 -    __ bind(Lloop);
   7.342 -    __ lduw(ary2_reg, limit_reg, chr2_reg);
   7.343 -    __ cmp(chr1_reg, chr2_reg);
   7.344 -    __ br(Assembler::notEqual, false, Assembler::pt, Ldone);
   7.345 -    __ delayed()->mov(G0, result_reg);     // not equal
   7.346 -    __ inccc(limit_reg, 2*sizeof(jchar));
   7.347 -    // annul LDUW if branch is not taken to prevent access past end of string
   7.348 -    __ br(Assembler::notZero, true, Assembler::pt, Lloop); //annul on taken
   7.349 -    __ delayed()->lduw(ary1_reg, limit_reg, chr1_reg); // hoisted
   7.350 -
   7.351 +
   7.352 +    // Compare char[] arrays aligned to 4 bytes.
   7.353 +    __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
   7.354 +                          chr1_reg, chr2_reg, Ldone);
   7.355      __ add(G0, 1, result_reg); // equals
   7.356  
   7.357      __ bind(Ldone);
   7.358 @@ -9471,33 +9375,33 @@
   7.359    ins_pipe(long_memory_op);
   7.360  %}
   7.361  
   7.362 -instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
   7.363 -                        o7RegI tmp3, flagsReg ccr) %{
   7.364 -  match(Set result (StrComp str1 str2));
   7.365 -  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
   7.366 +instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
   7.367 +                        o7RegI tmp, flagsReg ccr) %{
   7.368 +  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
   7.369 +  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
   7.370    ins_cost(300);
   7.371 -  format %{ "String Compare $str1,$str2 -> $result" %}
   7.372 -  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
   7.373 +  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp" %}
   7.374 +  ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
   7.375    ins_pipe(long_memory_op);
   7.376  %}
   7.377  
   7.378 -instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
   7.379 -                       o7RegI tmp3, flagsReg ccr) %{
   7.380 -  match(Set result (StrEquals str1 str2));
   7.381 -  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
   7.382 +instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
   7.383 +                       o7RegI tmp, flagsReg ccr) %{
   7.384 +  match(Set result (StrEquals (Binary str1 str2) cnt));
   7.385 +  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
   7.386    ins_cost(300);
   7.387 -  format %{ "String Equals $str1,$str2 -> $result" %}
   7.388 -  ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) );
   7.389 +  format %{ "String Equals $str1,$str2,$cnt -> $result   // KILL $tmp" %}
   7.390 +  ins_encode( enc_String_Equals(str1, str2, cnt, result) );
   7.391    ins_pipe(long_memory_op);
   7.392  %}
   7.393  
   7.394 -instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
   7.395 -                        flagsReg ccr) %{
   7.396 +instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
   7.397 +                      o7RegI tmp2, flagsReg ccr) %{
   7.398    match(Set result (AryEq ary1 ary2));
   7.399    effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
   7.400    ins_cost(300);
   7.401 -  format %{ "Array Equals $ary1,$ary2 -> $result" %}
   7.402 -  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
   7.403 +  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1,$tmp2" %}
   7.404 +  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result));
   7.405    ins_pipe(long_memory_op);
   7.406  %}
   7.407  
     8.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Fri Oct 02 11:26:25 2009 -0700
     8.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Oct 09 15:18:52 2009 -0700
     8.3 @@ -8404,6 +8404,319 @@
     8.4  }
     8.5  #endif // _LP64
     8.6  
     8.7 +// IndexOf substring.
     8.8 +void MacroAssembler::string_indexof(Register str1, Register str2,
     8.9 +                                    Register cnt1, Register cnt2, Register result,
    8.10 +                                    XMMRegister vec, Register tmp) {
    8.11 +  assert(UseSSE42Intrinsics, "SSE4.2 is required");
    8.12 +
    8.13 +  Label RELOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
    8.14 +        SCAN_SUBSTR, RET_NOT_FOUND, CLEANUP;
    8.15 +
    8.16 +  push(str1); // string addr
    8.17 +  push(str2); // substr addr
    8.18 +  push(cnt2); // substr count
    8.19 +  jmpb(PREP_FOR_SCAN);
    8.20 +
    8.21 +  // Substr count saved at sp
    8.22 +  // Substr saved at sp+1*wordSize
    8.23 +  // String saved at sp+2*wordSize
    8.24 +
    8.25 +  // Reload substr for rescan
    8.26 +  bind(RELOAD_SUBSTR);
    8.27 +  movl(cnt2, Address(rsp, 0));
    8.28 +  movptr(str2, Address(rsp, wordSize));
    8.29 +  // We came here after the beginninig of the substring was
    8.30 +  // matched but the rest of it was not so we need to search
    8.31 +  // again. Start from the next element after the previous match.
    8.32 +  subptr(str1, result); // Restore counter
    8.33 +  shrl(str1, 1);
    8.34 +  addl(cnt1, str1);
    8.35 +  lea(str1, Address(result, 2)); // Reload string
    8.36 +
    8.37 +  // Load substr
    8.38 +  bind(PREP_FOR_SCAN);
    8.39 +  movdqu(vec, Address(str2, 0));
    8.40 +  addl(cnt1, 8);  // prime the loop
    8.41 +  subptr(str1, 16);
    8.42 +
    8.43 +  // Scan string for substr in 16-byte vectors
    8.44 +  bind(SCAN_TO_SUBSTR);
    8.45 +  subl(cnt1, 8);
    8.46 +  addptr(str1, 16);
    8.47 +
    8.48 +  // pcmpestri
    8.49 +  //   inputs:
    8.50 +  //     xmm - substring
    8.51 +  //     rax - substring length (elements count)
    8.52 +  //     mem - scaned string
    8.53 +  //     rdx - string length (elements count)
    8.54 +  //     0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
    8.55 +  //   outputs:
    8.56 +  //     rcx - matched index in string
    8.57 +  assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
    8.58 +
    8.59 +  pcmpestri(vec, Address(str1, 0), 0x0d);
    8.60 +  jcc(Assembler::above, SCAN_TO_SUBSTR);      // CF == 0 && ZF == 0
    8.61 +  jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
    8.62 +
    8.63 +  // Fallthrough: found a potential substr
    8.64 +
    8.65 +  // Make sure string is still long enough
    8.66 +  subl(cnt1, tmp);
    8.67 +  cmpl(cnt1, cnt2);
    8.68 +  jccb(Assembler::negative, RET_NOT_FOUND);
    8.69 +  // Compute start addr of substr
    8.70 +  lea(str1, Address(str1, tmp, Address::times_2));
    8.71 +  movptr(result, str1); // save
    8.72 +
    8.73 +  // Compare potential substr
    8.74 +  addl(cnt1, 8);     // prime the loop
    8.75 +  addl(cnt2, 8);
    8.76 +  subptr(str1, 16);
    8.77 +  subptr(str2, 16);
    8.78 +
    8.79 +  // Scan 16-byte vectors of string and substr
    8.80 +  bind(SCAN_SUBSTR);
    8.81 +  subl(cnt1, 8);
    8.82 +  subl(cnt2, 8);
    8.83 +  addptr(str1, 16);
    8.84 +  addptr(str2, 16);
    8.85 +  movdqu(vec, Address(str2, 0));
    8.86 +  pcmpestri(vec, Address(str1, 0), 0x0d);
    8.87 +  jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
    8.88 +  jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
    8.89 +
    8.90 +  // Compute substr offset
    8.91 +  subptr(result, Address(rsp, 2*wordSize));
    8.92 +  shrl(result, 1); // index
    8.93 +  jmpb(CLEANUP);
    8.94 +
    8.95 +  bind(RET_NOT_FOUND);
    8.96 +  movl(result, -1);
    8.97 +
    8.98 +  bind(CLEANUP);
    8.99 +  addptr(rsp, 3*wordSize);
   8.100 +}
   8.101 +
   8.102 +// Compare strings.
   8.103 +void MacroAssembler::string_compare(Register str1, Register str2,
   8.104 +                                    Register cnt1, Register cnt2, Register result,
   8.105 +                                    XMMRegister vec1, XMMRegister vec2) {
   8.106 +  Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL;
   8.107 +
   8.108 +  // Compute the minimum of the string lengths and the
   8.109 +  // difference of the string lengths (stack).
   8.110 +  // Do the conditional move stuff
   8.111 +  movl(result, cnt1);
   8.112 +  subl(cnt1, cnt2);
   8.113 +  push(cnt1);
   8.114 +  if (VM_Version::supports_cmov()) {
   8.115 +    cmovl(Assembler::lessEqual, cnt2, result);
   8.116 +  } else {
   8.117 +    Label GT_LABEL;
   8.118 +    jccb(Assembler::greater, GT_LABEL);
   8.119 +    movl(cnt2, result);
   8.120 +    bind(GT_LABEL);
   8.121 +  }
   8.122 +
   8.123 +  // Is the minimum length zero?
   8.124 +  testl(cnt2, cnt2);
   8.125 +  jcc(Assembler::zero, LENGTH_DIFF_LABEL);
   8.126 +
   8.127 +  // Load first characters
   8.128 +  load_unsigned_short(result, Address(str1, 0));
   8.129 +  load_unsigned_short(cnt1, Address(str2, 0));
   8.130 +
   8.131 +  // Compare first characters
   8.132 +  subl(result, cnt1);
   8.133 +  jcc(Assembler::notZero,  POP_LABEL);
   8.134 +  decrementl(cnt2);
   8.135 +  jcc(Assembler::zero, LENGTH_DIFF_LABEL);
   8.136 +
   8.137 +  {
   8.138 +    // Check after comparing first character to see if strings are equivalent
   8.139 +    Label LSkip2;
   8.140 +    // Check if the strings start at same location
   8.141 +    cmpptr(str1, str2);
   8.142 +    jccb(Assembler::notEqual, LSkip2);
   8.143 +
   8.144 +    // Check if the length difference is zero (from stack)
   8.145 +    cmpl(Address(rsp, 0), 0x0);
   8.146 +    jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
   8.147 +
   8.148 +    // Strings might not be equivalent
   8.149 +    bind(LSkip2);
   8.150 +  }
   8.151 +
   8.152 +  // Advance to next character
   8.153 +  addptr(str1, 2);
   8.154 +  addptr(str2, 2);
   8.155 +
   8.156 +  if (UseSSE42Intrinsics) {
   8.157 +    // With SSE4.2, use double quad vector compare
   8.158 +    Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
   8.159 +    // Setup to compare 16-byte vectors
   8.160 +    movl(cnt1, cnt2);
   8.161 +    andl(cnt2, 0xfffffff8); // cnt2 holds the vector count
   8.162 +    andl(cnt1, 0x00000007); // cnt1 holds the tail count
   8.163 +    testl(cnt2, cnt2);
   8.164 +    jccb(Assembler::zero, COMPARE_TAIL);
   8.165 +
   8.166 +    lea(str2, Address(str2, cnt2, Address::times_2));
   8.167 +    lea(str1, Address(str1, cnt2, Address::times_2));
   8.168 +    negptr(cnt2);
   8.169 +
   8.170 +    bind(COMPARE_VECTORS);
   8.171 +    movdqu(vec1, Address(str1, cnt2, Address::times_2));
   8.172 +    movdqu(vec2, Address(str2, cnt2, Address::times_2));
   8.173 +    pxor(vec1, vec2);
   8.174 +    ptest(vec1, vec1);
   8.175 +    jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
   8.176 +    addptr(cnt2, 8);
   8.177 +    jcc(Assembler::notZero, COMPARE_VECTORS);
   8.178 +    jmpb(COMPARE_TAIL);
   8.179 +
   8.180 +    // Mismatched characters in the vectors
   8.181 +    bind(VECTOR_NOT_EQUAL);
   8.182 +    lea(str1, Address(str1, cnt2, Address::times_2));
   8.183 +    lea(str2, Address(str2, cnt2, Address::times_2));
   8.184 +    movl(cnt1, 8);
   8.185 +
   8.186 +    // Compare tail (< 8 chars), or rescan last vectors to
   8.187 +    // find 1st mismatched characters
   8.188 +    bind(COMPARE_TAIL);
   8.189 +    testl(cnt1, cnt1);
   8.190 +    jccb(Assembler::zero, LENGTH_DIFF_LABEL);
   8.191 +    movl(cnt2, cnt1);
   8.192 +    // Fallthru to tail compare
   8.193 +  }
   8.194 +
   8.195 +  // Shift str2 and str1 to the end of the arrays, negate min
   8.196 +  lea(str1, Address(str1, cnt2, Address::times_2, 0));
   8.197 +  lea(str2, Address(str2, cnt2, Address::times_2, 0));
   8.198 +  negptr(cnt2);
   8.199 +
   8.200 +    // Compare the rest of the characters
   8.201 +  bind(WHILE_HEAD_LABEL);
   8.202 +  load_unsigned_short(result, Address(str1, cnt2, Address::times_2, 0));
   8.203 +  load_unsigned_short(cnt1, Address(str2, cnt2, Address::times_2, 0));
   8.204 +  subl(result, cnt1);
   8.205 +  jccb(Assembler::notZero, POP_LABEL);
   8.206 +  increment(cnt2);
   8.207 +  jcc(Assembler::notZero, WHILE_HEAD_LABEL);
   8.208 +
   8.209 +  // Strings are equal up to min length.  Return the length difference.
   8.210 +  bind(LENGTH_DIFF_LABEL);
   8.211 +  pop(result);
   8.212 +  jmpb(DONE_LABEL);
   8.213 +
   8.214 +  // Discard the stored length difference
   8.215 +  bind(POP_LABEL);
   8.216 +  addptr(rsp, wordSize);
   8.217 +
   8.218 +  // That's it
   8.219 +  bind(DONE_LABEL);
   8.220 +}
   8.221 +
   8.222 +// Compare char[] arrays aligned to 4 bytes or substrings.
   8.223 +void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
   8.224 +                                        Register limit, Register result, Register chr,
   8.225 +                                        XMMRegister vec1, XMMRegister vec2) {
   8.226 +  Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
   8.227 +
   8.228 +  int length_offset  = arrayOopDesc::length_offset_in_bytes();
   8.229 +  int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
   8.230 +
   8.231 +  // Check the input args
   8.232 +  cmpptr(ary1, ary2);
   8.233 +  jcc(Assembler::equal, TRUE_LABEL);
   8.234 +
   8.235 +  if (is_array_equ) {
   8.236 +    // Need additional checks for arrays_equals.
   8.237 +    andptr(ary1, ary2);
   8.238 +    jcc(Assembler::zero, FALSE_LABEL); // One pointer is NULL
   8.239 +
   8.240 +    // Check the lengths
   8.241 +    movl(limit, Address(ary1, length_offset));
   8.242 +    cmpl(limit, Address(ary2, length_offset));
   8.243 +    jcc(Assembler::notEqual, FALSE_LABEL);
   8.244 +  }
   8.245 +
   8.246 +  // count == 0
   8.247 +  testl(limit, limit);
   8.248 +  jcc(Assembler::zero, TRUE_LABEL);
   8.249 +
   8.250 +  if (is_array_equ) {
   8.251 +    // Load array address
   8.252 +    lea(ary1, Address(ary1, base_offset));
   8.253 +    lea(ary2, Address(ary2, base_offset));
   8.254 +  }
   8.255 +
   8.256 +  shll(limit, 1);      // byte count != 0
   8.257 +  movl(result, limit); // copy
   8.258 +
   8.259 +  if (UseSSE42Intrinsics) {
   8.260 +    // With SSE4.2, use double quad vector compare
   8.261 +    Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
   8.262 +    // Compare 16-byte vectors
   8.263 +    andl(result, 0x0000000e);  //   tail count (in bytes)
   8.264 +    andl(limit, 0xfffffff0);   // vector count (in bytes)
   8.265 +    jccb(Assembler::zero, COMPARE_TAIL);
   8.266 +
   8.267 +    lea(ary1, Address(ary1, limit, Address::times_1));
   8.268 +    lea(ary2, Address(ary2, limit, Address::times_1));
   8.269 +    negptr(limit);
   8.270 +
   8.271 +    bind(COMPARE_WIDE_VECTORS);
   8.272 +    movdqu(vec1, Address(ary1, limit, Address::times_1));
   8.273 +    movdqu(vec2, Address(ary2, limit, Address::times_1));
   8.274 +    pxor(vec1, vec2);
   8.275 +    ptest(vec1, vec1);
   8.276 +    jccb(Assembler::notZero, FALSE_LABEL);
   8.277 +    addptr(limit, 16);
   8.278 +    jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
   8.279 +
   8.280 +    bind(COMPARE_TAIL); // limit is zero
   8.281 +    movl(limit, result);
   8.282 +    // Fallthru to tail compare
   8.283 +  }
   8.284 +
   8.285 +  // Compare 4-byte vectors
   8.286 +  andl(limit, 0xfffffffc); // vector count (in bytes)
   8.287 +  jccb(Assembler::zero, COMPARE_CHAR);
   8.288 +
   8.289 +  lea(ary1, Address(ary1, limit, Address::times_1));
   8.290 +  lea(ary2, Address(ary2, limit, Address::times_1));
   8.291 +  negptr(limit);
   8.292 +
   8.293 +  bind(COMPARE_VECTORS);
   8.294 +  movl(chr, Address(ary1, limit, Address::times_1));
   8.295 +  cmpl(chr, Address(ary2, limit, Address::times_1));
   8.296 +  jccb(Assembler::notEqual, FALSE_LABEL);
   8.297 +  addptr(limit, 4);
   8.298 +  jcc(Assembler::notZero, COMPARE_VECTORS);
   8.299 +
   8.300 +  // Compare trailing char (final 2 bytes), if any
   8.301 +  bind(COMPARE_CHAR);
   8.302 +  testl(result, 0x2);   // tail  char
   8.303 +  jccb(Assembler::zero, TRUE_LABEL);
   8.304 +  load_unsigned_short(chr, Address(ary1, 0));
   8.305 +  load_unsigned_short(limit, Address(ary2, 0));
   8.306 +  cmpl(chr, limit);
   8.307 +  jccb(Assembler::notEqual, FALSE_LABEL);
   8.308 +
   8.309 +  bind(TRUE_LABEL);
   8.310 +  movl(result, 1);   // return true
   8.311 +  jmpb(DONE);
   8.312 +
   8.313 +  bind(FALSE_LABEL);
   8.314 +  xorl(result, result); // return false
   8.315 +
   8.316 +  // That's it
   8.317 +  bind(DONE);
   8.318 +}
   8.319 +
   8.320  Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
   8.321    switch (cond) {
   8.322      // Note some conditions are synonyms for others
     9.1 --- a/src/cpu/x86/vm/assembler_x86.hpp	Fri Oct 02 11:26:25 2009 -0700
     9.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp	Fri Oct 09 15:18:52 2009 -0700
     9.3 @@ -2206,6 +2206,20 @@
     9.4    void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
     9.5    void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
     9.6  
     9.7 +  // IndexOf strings.
     9.8 +  void string_indexof(Register str1, Register str2,
     9.9 +                      Register cnt1, Register cnt2, Register result,
    9.10 +                      XMMRegister vec, Register tmp);
    9.11 +
    9.12 +  // Compare strings.
    9.13 +  void string_compare(Register str1, Register str2,
    9.14 +                      Register cnt1, Register cnt2, Register result,
    9.15 +                      XMMRegister vec1, XMMRegister vec2);
    9.16 +
    9.17 +  // Compare char[] arrays.
    9.18 +  void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
    9.19 +                          Register limit, Register result, Register chr,
    9.20 +                          XMMRegister vec1, XMMRegister vec2);
    9.21  
    9.22  #undef VIRTUAL
    9.23  
    10.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Oct 02 11:26:25 2009 -0700
    10.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Oct 09 15:18:52 2009 -0700
    10.3 @@ -1638,7 +1638,7 @@
    10.4        jobject2reg_with_patching(k_RInfo, op->info_for_patch());
    10.5      } else {
    10.6  #ifdef _LP64
    10.7 -      __ movoop(k_RInfo, k->encoding());
    10.8 +      __ movoop(k_RInfo, k->constant_encoding());
    10.9  #else
   10.10        k_RInfo = noreg;
   10.11  #endif // _LP64
   10.12 @@ -1661,7 +1661,7 @@
   10.13        assert(data != NULL,       "need data for checkcast");
   10.14        assert(data->is_BitData(), "need BitData for checkcast");
   10.15        Register mdo  = klass_RInfo;
   10.16 -      __ movoop(mdo, md->encoding());
   10.17 +      __ movoop(mdo, md->constant_encoding());
   10.18        Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
   10.19        int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
   10.20        __ orl(data_addr, header_bits);
   10.21 @@ -1679,7 +1679,7 @@
   10.22  #ifdef _LP64
   10.23          __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   10.24  #else
   10.25 -        __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding());
   10.26 +        __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
   10.27  #endif // _LP64
   10.28        } else {
   10.29          __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   10.30 @@ -1696,7 +1696,7 @@
   10.31  #ifdef _LP64
   10.32          __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));
   10.33  #else
   10.34 -        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding());
   10.35 +        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
   10.36  #endif // _LP64
   10.37          if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
   10.38            __ jcc(Assembler::notEqual, *stub->entry());
   10.39 @@ -1707,7 +1707,7 @@
   10.40  #ifdef _LP64
   10.41            __ cmpptr(klass_RInfo, k_RInfo);
   10.42  #else
   10.43 -          __ cmpoop(klass_RInfo, k->encoding());
   10.44 +          __ cmpoop(klass_RInfo, k->constant_encoding());
   10.45  #endif // _LP64
   10.46            __ jcc(Assembler::equal, done);
   10.47  
   10.48 @@ -1715,7 +1715,7 @@
   10.49  #ifdef _LP64
   10.50            __ push(k_RInfo);
   10.51  #else
   10.52 -          __ pushoop(k->encoding());
   10.53 +          __ pushoop(k->constant_encoding());
   10.54  #endif // _LP64
   10.55            __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   10.56            __ pop(klass_RInfo);
   10.57 @@ -1763,7 +1763,7 @@
   10.58      if (!k->is_loaded()) {
   10.59        jobject2reg_with_patching(k_RInfo, op->info_for_patch());
   10.60      } else {
   10.61 -      LP64_ONLY(__ movoop(k_RInfo, k->encoding()));
   10.62 +      LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding()));
   10.63      }
   10.64      assert(obj != k_RInfo, "must be different");
   10.65  
   10.66 @@ -1774,7 +1774,7 @@
   10.67        // get object class
   10.68        // not a safepoint as obj null check happens earlier
   10.69        if (LP64_ONLY(false &&) k->is_loaded()) {
   10.70 -        NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()));
   10.71 +        NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()));
   10.72          k_RInfo = noreg;
   10.73        } else {
   10.74          __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   10.75 @@ -1791,14 +1791,14 @@
   10.76  #ifndef _LP64
   10.77        if (k->is_loaded()) {
   10.78          // See if we get an immediate positive hit
   10.79 -        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding());
   10.80 +        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
   10.81          __ jcc(Assembler::equal, one);
   10.82          if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) {
   10.83            // check for self
   10.84 -          __ cmpoop(klass_RInfo, k->encoding());
   10.85 +          __ cmpoop(klass_RInfo, k->constant_encoding());
   10.86            __ jcc(Assembler::equal, one);
   10.87            __ push(klass_RInfo);
   10.88 -          __ pushoop(k->encoding());
   10.89 +          __ pushoop(k->constant_encoding());
   10.90            __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   10.91            __ pop(klass_RInfo);
   10.92            __ pop(dst);
   10.93 @@ -3112,7 +3112,7 @@
   10.94      // subtype which we can't check or src is the same array as dst
   10.95      // but not necessarily exactly of type default_type.
   10.96      Label known_ok, halt;
   10.97 -    __ movoop(tmp, default_type->encoding());
   10.98 +    __ movoop(tmp, default_type->constant_encoding());
   10.99      if (basic_type != T_OBJECT) {
  10.100        __ cmpptr(tmp, dst_klass_addr);
  10.101        __ jcc(Assembler::notEqual, halt);
  10.102 @@ -3200,7 +3200,7 @@
  10.103    assert(data->is_CounterData(), "need CounterData for calls");
  10.104    assert(op->mdo()->is_single_cpu(),  "mdo must be allocated");
  10.105    Register mdo  = op->mdo()->as_register();
  10.106 -  __ movoop(mdo, md->encoding());
  10.107 +  __ movoop(mdo, md->constant_encoding());
  10.108    Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
  10.109    __ addl(counter_addr, DataLayout::counter_increment);
  10.110    Bytecodes::Code bc = method->java_code_at_bci(bci);
  10.111 @@ -3240,7 +3240,7 @@
  10.112          ciKlass* receiver = vc_data->receiver(i);
  10.113          if (receiver == NULL) {
  10.114            Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
  10.115 -          __ movoop(recv_addr, known_klass->encoding());
  10.116 +          __ movoop(recv_addr, known_klass->constant_encoding());
  10.117            Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
  10.118            __ addl(data_addr, DataLayout::counter_increment);
  10.119            return;
    11.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Fri Oct 02 11:26:25 2009 -0700
    11.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Fri Oct 09 15:18:52 2009 -0700
    11.3 @@ -994,7 +994,7 @@
    11.4    LIR_Opr len = length.result();
    11.5    BasicType elem_type = x->elt_type();
    11.6  
    11.7 -  __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
    11.8 +  __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
    11.9  
   11.10    CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
   11.11    __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
    12.1 --- a/src/cpu/x86/vm/x86_32.ad	Fri Oct 02 11:26:25 2009 -0700
    12.2 +++ b/src/cpu/x86/vm/x86_32.ad	Fri Oct 09 15:18:52 2009 -0700
    12.3 @@ -379,7 +379,7 @@
    12.4          int format) {
    12.5  #ifdef ASSERT
    12.6    if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
    12.7 -    assert(oop(d32)->is_oop() && oop(d32)->is_perm(), "cannot embed non-perm oops in code");
    12.8 +    assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
    12.9    }
   12.10  #endif
   12.11    cbuf.relocate(cbuf.inst_mark(), rspec, format);
   12.12 @@ -3701,458 +3701,6 @@
   12.13      }
   12.14    %}
   12.15  
   12.16 -  enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
   12.17 -                        eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{
   12.18 -    Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL,
   12.19 -          POP_LABEL, DONE_LABEL, CONT_LABEL,
   12.20 -          WHILE_HEAD_LABEL;
   12.21 -    MacroAssembler masm(&cbuf);
   12.22 -
   12.23 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
   12.24 -    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
   12.25 -
   12.26 -    // Get the first character position in both strings
   12.27 -    //         [8] char array, [12] offset, [16] count
   12.28 -    int value_offset  = java_lang_String::value_offset_in_bytes();
   12.29 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
   12.30 -    int count_offset  = java_lang_String::count_offset_in_bytes();
   12.31 -    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
   12.32 -
   12.33 -    masm.movptr(rax, Address(rsi, value_offset));
   12.34 -    masm.movl(rcx, Address(rsi, offset_offset));
   12.35 -    masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
   12.36 -    masm.movptr(rbx, Address(rdi, value_offset));
   12.37 -    masm.movl(rcx, Address(rdi, offset_offset));
   12.38 -    masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
   12.39 -
   12.40 -    // Compute the minimum of the string lengths(rsi) and the
   12.41 -    // difference of the string lengths (stack)
   12.42 -
   12.43 -    if (VM_Version::supports_cmov()) {
   12.44 -      masm.movl(rdi, Address(rdi, count_offset));
   12.45 -      masm.movl(rsi, Address(rsi, count_offset));
   12.46 -      masm.movl(rcx, rdi);
   12.47 -      masm.subl(rdi, rsi);
   12.48 -      masm.push(rdi);
   12.49 -      masm.cmovl(Assembler::lessEqual, rsi, rcx);
   12.50 -    } else {
   12.51 -      masm.movl(rdi, Address(rdi, count_offset));
   12.52 -      masm.movl(rcx, Address(rsi, count_offset));
   12.53 -      masm.movl(rsi, rdi);
   12.54 -      masm.subl(rdi, rcx);
   12.55 -      masm.push(rdi);
   12.56 -      masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);
   12.57 -      masm.movl(rsi, rcx);
   12.58 -      // rsi holds min, rcx is unused
   12.59 -    }
   12.60 -
   12.61 -    // Is the minimum length zero?
   12.62 -    masm.bind(ECX_GOOD_LABEL);
   12.63 -    masm.testl(rsi, rsi);
   12.64 -    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
   12.65 -
   12.66 -    // Load first characters
   12.67 -    masm.load_unsigned_short(rcx, Address(rbx, 0));
   12.68 -    masm.load_unsigned_short(rdi, Address(rax, 0));
   12.69 -
   12.70 -    // Compare first characters
   12.71 -    masm.subl(rcx, rdi);
   12.72 -    masm.jcc(Assembler::notZero,  POP_LABEL);
   12.73 -    masm.decrementl(rsi);
   12.74 -    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
   12.75 -
   12.76 -    {
   12.77 -      // Check after comparing first character to see if strings are equivalent
   12.78 -      Label LSkip2;
   12.79 -      // Check if the strings start at same location
   12.80 -      masm.cmpptr(rbx,rax);
   12.81 -      masm.jccb(Assembler::notEqual, LSkip2);
   12.82 -
   12.83 -      // Check if the length difference is zero (from stack)
   12.84 -      masm.cmpl(Address(rsp, 0), 0x0);
   12.85 -      masm.jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
   12.86 -
   12.87 -      // Strings might not be equivalent
   12.88 -      masm.bind(LSkip2);
   12.89 -    }
   12.90 -
   12.91 -   // Advance to next character
   12.92 -    masm.addptr(rax, 2);
   12.93 -    masm.addptr(rbx, 2);
   12.94 -
   12.95 -    if (UseSSE42Intrinsics) {
   12.96 -      // With SSE4.2, use double quad vector compare
   12.97 -      Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
   12.98 -      // Setup to compare 16-byte vectors
   12.99 -      masm.movl(rdi, rsi);
  12.100 -      masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
  12.101 -      masm.andl(rdi, 0x00000007); // rdi holds the tail count
  12.102 -      masm.testl(rsi, rsi);
  12.103 -      masm.jccb(Assembler::zero, COMPARE_TAIL);
  12.104 -
  12.105 -      masm.lea(rax, Address(rax, rsi, Address::times_2));
  12.106 -      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
  12.107 -      masm.negl(rsi);
  12.108 -
  12.109 -      masm.bind(COMPARE_VECTORS);
  12.110 -      masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
  12.111 -      masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
  12.112 -      masm.pxor(tmp1Reg, tmp2Reg);
  12.113 -      masm.ptest(tmp1Reg, tmp1Reg);
  12.114 -      masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
  12.115 -      masm.addl(rsi, 8);
  12.116 -      masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  12.117 -      masm.jmpb(COMPARE_TAIL);
  12.118 -
  12.119 -      // Mismatched characters in the vectors
  12.120 -      masm.bind(VECTOR_NOT_EQUAL);
  12.121 -      masm.lea(rax, Address(rax, rsi, Address::times_2));
  12.122 -      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
  12.123 -      masm.movl(rdi, 8);
  12.124 -
  12.125 -      // Compare tail (< 8 chars), or rescan last vectors to
  12.126 -      // find 1st mismatched characters
  12.127 -      masm.bind(COMPARE_TAIL);
  12.128 -      masm.testl(rdi, rdi);
  12.129 -      masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
  12.130 -      masm.movl(rsi, rdi);
  12.131 -      // Fallthru to tail compare
  12.132 -    }
  12.133 -
  12.134 -    //Shift rax, and rbx, to the end of the arrays, negate min
  12.135 -    masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
  12.136 -    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
  12.137 -    masm.negl(rsi);
  12.138 -
  12.139 -    // Compare the rest of the characters
  12.140 -    masm.bind(WHILE_HEAD_LABEL);
  12.141 -    masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
  12.142 -    masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
  12.143 -    masm.subl(rcx, rdi);
  12.144 -    masm.jccb(Assembler::notZero, POP_LABEL);
  12.145 -    masm.incrementl(rsi);
  12.146 -    masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
  12.147 -
  12.148 -    // Strings are equal up to min length.  Return the length difference.
  12.149 -    masm.bind(LENGTH_DIFF_LABEL);
  12.150 -    masm.pop(rcx);
  12.151 -    masm.jmpb(DONE_LABEL);
  12.152 -
  12.153 -    // Discard the stored length difference
  12.154 -    masm.bind(POP_LABEL);
  12.155 -    masm.addptr(rsp, 4);
  12.156 -
  12.157 -    // That's it
  12.158 -    masm.bind(DONE_LABEL);
  12.159 -  %}
  12.160 -
  12.161 - enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
  12.162 -                       eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{
  12.163 -    Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  12.164 -    MacroAssembler masm(&cbuf);
  12.165 -
  12.166 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  12.167 -    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  12.168 -
  12.169 -    int value_offset  = java_lang_String::value_offset_in_bytes();
  12.170 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
  12.171 -    int count_offset  = java_lang_String::count_offset_in_bytes();
  12.172 -    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  12.173 -
  12.174 -    // does source == target string?
  12.175 -    masm.cmpptr(rdi, rsi);
  12.176 -    masm.jcc(Assembler::equal, RET_TRUE);
  12.177 -
  12.178 -    // get and compare counts
  12.179 -    masm.movl(rcx, Address(rdi, count_offset));
  12.180 -    masm.movl(rax, Address(rsi, count_offset));
  12.181 -    masm.cmpl(rcx, rax);
  12.182 -    masm.jcc(Assembler::notEqual, RET_FALSE);
  12.183 -    masm.testl(rax, rax);
  12.184 -    masm.jcc(Assembler::zero, RET_TRUE);
  12.185 -
  12.186 -    // get source string offset and value
  12.187 -    masm.movptr(rbx, Address(rsi, value_offset));
  12.188 -    masm.movl(rax, Address(rsi, offset_offset));
  12.189 -    masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));
  12.190 -
  12.191 -    // get compare string offset and value
  12.192 -    masm.movptr(rbx, Address(rdi, value_offset));
  12.193 -    masm.movl(rax, Address(rdi, offset_offset));
  12.194 -    masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));
  12.195 -
  12.196 -    // Set byte count
  12.197 -    masm.shll(rcx, 1);
  12.198 -    masm.movl(rax, rcx);
  12.199 -
  12.200 -    if (UseSSE42Intrinsics) {
  12.201 -      // With SSE4.2, use double quad vector compare
  12.202 -      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  12.203 -      // Compare 16-byte vectors
  12.204 -      masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
  12.205 -      masm.andl(rax, 0x0000000e);  // tail count (in bytes)
  12.206 -      masm.testl(rcx, rcx);
  12.207 -      masm.jccb(Assembler::zero, COMPARE_TAIL);
  12.208 -      masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  12.209 -      masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  12.210 -      masm.negl(rcx);
  12.211 -
  12.212 -      masm.bind(COMPARE_WIDE_VECTORS);
  12.213 -      masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
  12.214 -      masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
  12.215 -      masm.pxor(tmp1Reg, tmp2Reg);
  12.216 -      masm.ptest(tmp1Reg, tmp1Reg);
  12.217 -      masm.jccb(Assembler::notZero, RET_FALSE);
  12.218 -      masm.addl(rcx, 16);
  12.219 -      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  12.220 -      masm.bind(COMPARE_TAIL);
  12.221 -      masm.movl(rcx, rax);
  12.222 -      // Fallthru to tail compare
  12.223 -    }
  12.224 -
  12.225 -    // Compare 4-byte vectors
  12.226 -    masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
  12.227 -    masm.andl(rax, 0x00000002);  // tail char (in bytes)
  12.228 -    masm.testl(rcx, rcx);
  12.229 -    masm.jccb(Assembler::zero, COMPARE_CHAR);
  12.230 -    masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  12.231 -    masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  12.232 -    masm.negl(rcx);
  12.233 -
  12.234 -    masm.bind(COMPARE_VECTORS);
  12.235 -    masm.movl(rbx, Address(rdi, rcx, Address::times_1));
  12.236 -    masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
  12.237 -    masm.jccb(Assembler::notEqual, RET_FALSE);
  12.238 -    masm.addl(rcx, 4);
  12.239 -    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  12.240 -
  12.241 -    // Compare trailing char (final 2 bytes), if any
  12.242 -    masm.bind(COMPARE_CHAR);
  12.243 -    masm.testl(rax, rax);
  12.244 -    masm.jccb(Assembler::zero, RET_TRUE);
  12.245 -    masm.load_unsigned_short(rbx, Address(rdi, 0));
  12.246 -    masm.load_unsigned_short(rcx, Address(rsi, 0));
  12.247 -    masm.cmpl(rbx, rcx);
  12.248 -    masm.jccb(Assembler::notEqual, RET_FALSE);
  12.249 -
  12.250 -    masm.bind(RET_TRUE);
  12.251 -    masm.movl(rax, 1);   // return true
  12.252 -    masm.jmpb(DONE);
  12.253 -
  12.254 -    masm.bind(RET_FALSE);
  12.255 -    masm.xorl(rax, rax); // return false
  12.256 -
  12.257 -    masm.bind(DONE);
  12.258 -    %}
  12.259 -
  12.260 - enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
  12.261 -                        eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{
  12.262 -    // SSE4.2 version
  12.263 -    Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
  12.264 -          SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
  12.265 -    MacroAssembler masm(&cbuf);
  12.266 -
  12.267 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  12.268 -
  12.269 -    // Get the first character position in both strings
  12.270 -    //         [8] char array, [12] offset, [16] count
  12.271 -    int value_offset  = java_lang_String::value_offset_in_bytes();
  12.272 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
  12.273 -    int count_offset  = java_lang_String::count_offset_in_bytes();
  12.274 -    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  12.275 -
  12.276 -    // Get counts for string and substr
  12.277 -    masm.movl(rdx, Address(rsi, count_offset));
  12.278 -    masm.movl(rax, Address(rdi, count_offset));
  12.279 -    // Check for substr count > string count
  12.280 -    masm.cmpl(rax, rdx);
  12.281 -    masm.jcc(Assembler::greater, RET_NEG_ONE);
  12.282 -
  12.283 -    // Start the indexOf operation
  12.284 -    // Get start addr of string
  12.285 -    masm.movptr(rbx, Address(rsi, value_offset));
  12.286 -    masm.movl(rcx, Address(rsi, offset_offset));
  12.287 -    masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
  12.288 -    masm.push(rsi);
  12.289 -
  12.290 -    // Get start addr of substr
  12.291 -    masm.movptr(rbx, Address(rdi, value_offset));
  12.292 -    masm.movl(rcx, Address(rdi, offset_offset));
  12.293 -    masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
  12.294 -    masm.push(rdi);
  12.295 -    masm.push(rax);
  12.296 -    masm.jmpb(PREP_FOR_SCAN);
  12.297 -
  12.298 -    // Substr count saved at sp
  12.299 -    // Substr saved at sp+4
  12.300 -    // String saved at sp+8
  12.301 -
  12.302 -    // Prep to load substr for scan
  12.303 -    masm.bind(LOAD_SUBSTR);
  12.304 -    masm.movptr(rdi, Address(rsp, 4));
  12.305 -    masm.movl(rax, Address(rsp, 0));
  12.306 -
  12.307 -    // Load substr
  12.308 -    masm.bind(PREP_FOR_SCAN);
  12.309 -    masm.movdqu(tmp1Reg, Address(rdi, 0));
  12.310 -    masm.addl(rdx, 8);        // prime the loop
  12.311 -    masm.subptr(rsi, 16);
  12.312 -
  12.313 -    // Scan string for substr in 16-byte vectors
  12.314 -    masm.bind(SCAN_TO_SUBSTR);
  12.315 -    masm.subl(rdx, 8);
  12.316 -    masm.addptr(rsi, 16);
  12.317 -    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  12.318 -    masm.jcc(Assembler::above, SCAN_TO_SUBSTR);     // CF == 0 && ZF == 0
  12.319 -    masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
  12.320 -
  12.321 -    // Fallthru: found a potential substr
  12.322 -
  12.323 -    // Make sure string is still long enough
  12.324 -    masm.subl(rdx, rcx);
  12.325 -    masm.cmpl(rdx, rax);
  12.326 -    masm.jccb(Assembler::negative, RET_NOT_FOUND);
  12.327 -    // Compute start addr of substr
  12.328 -    masm.lea(rsi, Address(rsi, rcx, Address::times_2));
  12.329 -    masm.movptr(rbx, rsi);
  12.330 -
  12.331 -    // Compare potential substr
  12.332 -    masm.addl(rdx, 8);        // prime the loop
  12.333 -    masm.addl(rax, 8);
  12.334 -    masm.subptr(rsi, 16);
  12.335 -    masm.subptr(rdi, 16);
  12.336 -
  12.337 -    // Scan 16-byte vectors of string and substr
  12.338 -    masm.bind(SCAN_SUBSTR);
  12.339 -    masm.subl(rax, 8);
  12.340 -    masm.subl(rdx, 8);
  12.341 -    masm.addptr(rsi, 16);
  12.342 -    masm.addptr(rdi, 16);
  12.343 -    masm.movdqu(tmp1Reg, Address(rdi, 0));
  12.344 -    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  12.345 -    masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
  12.346 -    masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
  12.347 -
  12.348 -    // Compute substr offset
  12.349 -    masm.movptr(rsi, Address(rsp, 8));
  12.350 -    masm.subptr(rbx, rsi);
  12.351 -    masm.shrl(rbx, 1);
  12.352 -    masm.jmpb(CLEANUP);
  12.353 -
  12.354 -    masm.bind(RET_NEG_ONE);
  12.355 -    masm.movl(rbx, -1);
  12.356 -    masm.jmpb(DONE);
  12.357 -
  12.358 -    masm.bind(RET_NOT_FOUND);
  12.359 -    masm.movl(rbx, -1);
  12.360 -
  12.361 -    masm.bind(CLEANUP);
  12.362 -    masm.addptr(rsp, 12);
  12.363 -
  12.364 -    masm.bind(DONE);
  12.365 -  %}
  12.366 -
  12.367 -  enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,
  12.368 -                             eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{
  12.369 -    Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  12.370 -    MacroAssembler masm(&cbuf);
  12.371 -
  12.372 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  12.373 -    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  12.374 -    Register ary1Reg      = as_Register($ary1$$reg);
  12.375 -    Register ary2Reg      = as_Register($ary2$$reg);
  12.376 -    Register tmp3Reg      = as_Register($tmp3$$reg);
  12.377 -    Register tmp4Reg      = as_Register($tmp4$$reg);
  12.378 -    Register resultReg    = as_Register($result$$reg);
  12.379 -
  12.380 -    int length_offset  = arrayOopDesc::length_offset_in_bytes();
  12.381 -    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  12.382 -
  12.383 -    // Check the input args
  12.384 -    masm.cmpptr(ary1Reg, ary2Reg);
  12.385 -    masm.jcc(Assembler::equal, TRUE_LABEL);
  12.386 -    masm.testptr(ary1Reg, ary1Reg);
  12.387 -    masm.jcc(Assembler::zero, FALSE_LABEL);
  12.388 -    masm.testptr(ary2Reg, ary2Reg);
  12.389 -    masm.jcc(Assembler::zero, FALSE_LABEL);
  12.390 -
  12.391 -    // Check the lengths
  12.392 -    masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
  12.393 -    masm.movl(resultReg, Address(ary2Reg, length_offset));
  12.394 -    masm.cmpl(tmp4Reg, resultReg);
  12.395 -    masm.jcc(Assembler::notEqual, FALSE_LABEL);
  12.396 -    masm.testl(resultReg, resultReg);
  12.397 -    masm.jcc(Assembler::zero, TRUE_LABEL);
  12.398 -
  12.399 -    // Load array addrs
  12.400 -    masm.lea(ary1Reg, Address(ary1Reg, base_offset));
  12.401 -    masm.lea(ary2Reg, Address(ary2Reg, base_offset));
  12.402 -
  12.403 -    // Set byte count
  12.404 -    masm.shll(tmp4Reg, 1);
  12.405 -    masm.movl(resultReg, tmp4Reg);
  12.406 -
  12.407 -    if (UseSSE42Intrinsics) {
  12.408 -      // With SSE4.2, use double quad vector compare
  12.409 -      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  12.410 -      // Compare 16-byte vectors
  12.411 -      masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
  12.412 -      masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
  12.413 -      masm.testl(tmp4Reg, tmp4Reg);
  12.414 -      masm.jccb(Assembler::zero, COMPARE_TAIL);
  12.415 -      masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  12.416 -      masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  12.417 -      masm.negl(tmp4Reg);
  12.418 -
  12.419 -      masm.bind(COMPARE_WIDE_VECTORS);
  12.420 -      masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  12.421 -      masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  12.422 -      masm.pxor(tmp1Reg, tmp2Reg);
  12.423 -      masm.ptest(tmp1Reg, tmp1Reg);
  12.424 -
  12.425 -      masm.jccb(Assembler::notZero, FALSE_LABEL);
  12.426 -      masm.addl(tmp4Reg, 16);
  12.427 -      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  12.428 -      masm.bind(COMPARE_TAIL);
  12.429 -      masm.movl(tmp4Reg, resultReg);
  12.430 -      // Fallthru to tail compare
  12.431 -    }
  12.432 -
  12.433 -    // Compare 4-byte vectors
  12.434 -    masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
  12.435 -    masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
  12.436 -    masm.testl(tmp4Reg, tmp4Reg);
  12.437 -    masm.jccb(Assembler::zero, COMPARE_CHAR);
  12.438 -    masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  12.439 -    masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  12.440 -    masm.negl(tmp4Reg);
  12.441 -
  12.442 -    masm.bind(COMPARE_VECTORS);
  12.443 -    masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  12.444 -    masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  12.445 -    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  12.446 -    masm.addl(tmp4Reg, 4);
  12.447 -    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  12.448 -
  12.449 -    // Compare trailing char (final 2 bytes), if any
  12.450 -    masm.bind(COMPARE_CHAR);
  12.451 -    masm.testl(resultReg, resultReg);
  12.452 -    masm.jccb(Assembler::zero, TRUE_LABEL);
  12.453 -    masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
  12.454 -    masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
  12.455 -    masm.cmpl(tmp3Reg, tmp4Reg);
  12.456 -    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  12.457 -
  12.458 -    masm.bind(TRUE_LABEL);
  12.459 -    masm.movl(resultReg, 1);   // return true
  12.460 -    masm.jmpb(DONE);
  12.461 -
  12.462 -    masm.bind(FALSE_LABEL);
  12.463 -    masm.xorl(resultReg, resultReg); // return false
  12.464 -
  12.465 -    // That's it
  12.466 -    masm.bind(DONE);
  12.467 -  %}
  12.468  
  12.469    enc_class enc_pop_rdx() %{
  12.470      emit_opcode(cbuf,0x5A);
  12.471 @@ -12718,48 +12266,64 @@
  12.472    ins_pipe( pipe_slow );
  12.473  %}
  12.474  
  12.475 -instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
  12.476 -                        eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{
  12.477 -  match(Set result (StrComp str1 str2));
  12.478 -  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  12.479 -  //ins_cost(300);
  12.480 -
  12.481 -  format %{ "String Compare $str1,$str2 -> $result    // KILL EAX, EBX" %}
  12.482 -  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  12.483 +instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2,
  12.484 +                        eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{
  12.485 +  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
  12.486 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
  12.487 +
  12.488 +  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
  12.489 +  ins_encode %{
  12.490 +    __ string_compare($str1$$Register, $str2$$Register,
  12.491 +                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
  12.492 +                      $tmp1$$XMMRegister, $tmp2$$XMMRegister);
  12.493 +  %}
  12.494    ins_pipe( pipe_slow );
  12.495  %}
  12.496  
  12.497  // fast string equals
  12.498 -instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
  12.499 -                       eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
  12.500 -  match(Set result (StrEquals str1 str2));
  12.501 -  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  12.502 -
  12.503 -  format %{ "String Equals $str1,$str2 -> $result    // KILL EBX, ECX" %}
  12.504 -  ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) );
  12.505 -  ins_pipe( pipe_slow );
  12.506 -%}
  12.507 -
  12.508 -instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
  12.509 -                        eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{
  12.510 +instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
  12.511 +                       regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
  12.512 +  match(Set result (StrEquals (Binary str1 str2) cnt));
  12.513 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
  12.514 +
  12.515 +  format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
  12.516 +  ins_encode %{
  12.517 +    __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
  12.518 +                          $cnt$$Register, $result$$Register, $tmp3$$Register,
  12.519 +                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
  12.520 +  %}
  12.521 +  ins_pipe( pipe_slow );
  12.522 +%}
  12.523 +
  12.524 +instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
  12.525 +                        eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
  12.526    predicate(UseSSE42Intrinsics);
  12.527 -  match(Set result (StrIndexOf str1 str2));
  12.528 -  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
  12.529 -
  12.530 -  format %{ "String IndexOf $str1,$str2 -> $result    // KILL EAX, ECX, EDX" %}
  12.531 -  ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  12.532 +  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
  12.533 +  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
  12.534 +
  12.535 +  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp2, $tmp1" %}
  12.536 +  ins_encode %{
  12.537 +    __ string_indexof($str1$$Register, $str2$$Register,
  12.538 +                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
  12.539 +                      $tmp1$$XMMRegister, $tmp2$$Register);
  12.540 +  %}
  12.541    ins_pipe( pipe_slow );
  12.542  %}
  12.543  
  12.544  // fast array equals
  12.545 -instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3,
  12.546 -                      eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
  12.547 +instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
  12.548 +                      regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
  12.549 +%{
  12.550    match(Set result (AryEq ary1 ary2));
  12.551    effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
  12.552    //ins_cost(300);
  12.553  
  12.554 -  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL EBX, EDX" %}
  12.555 -  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
  12.556 +  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
  12.557 +  ins_encode %{
  12.558 +    __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
  12.559 +                          $tmp3$$Register, $result$$Register, $tmp4$$Register,
  12.560 +                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
  12.561 +  %}
  12.562    ins_pipe( pipe_slow );
  12.563  %}
  12.564  
    13.1 --- a/src/cpu/x86/vm/x86_64.ad	Fri Oct 02 11:26:25 2009 -0700
    13.2 +++ b/src/cpu/x86/vm/x86_64.ad	Fri Oct 09 15:18:52 2009 -0700
    13.3 @@ -683,7 +683,7 @@
    13.4  #ifdef ASSERT
    13.5    if (rspec.reloc()->type() == relocInfo::oop_type &&
    13.6        d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
    13.7 -    assert(oop((intptr_t)d32)->is_oop() && oop((intptr_t)d32)->is_perm(), "cannot embed non-perm oops in code");
    13.8 +    assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
    13.9    }
   13.10  #endif
   13.11    cbuf.relocate(cbuf.inst_mark(), rspec, format);
   13.12 @@ -721,8 +721,8 @@
   13.13  #ifdef ASSERT
   13.14    if (rspec.reloc()->type() == relocInfo::oop_type &&
   13.15        d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
   13.16 -    assert(oop(d64)->is_oop() && oop(d64)->is_perm(),
   13.17 -           "cannot embed non-perm oops in code");
   13.18 +    assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
   13.19 +           "cannot embed scavengable oops in code");
   13.20    }
   13.21  #endif
   13.22    cbuf.relocate(cbuf.inst_mark(), rspec, format);
   13.23 @@ -3701,448 +3701,6 @@
   13.24      }
   13.25    %}
   13.26  
   13.27 -  enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
   13.28 -                        rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
   13.29 -    Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL,
   13.30 -          POP_LABEL, DONE_LABEL, CONT_LABEL,
   13.31 -          WHILE_HEAD_LABEL;
   13.32 -    MacroAssembler masm(&cbuf);
   13.33 -
   13.34 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
   13.35 -    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
   13.36 -
   13.37 -    // Get the first character position in both strings
   13.38 -    //         [8] char array, [12] offset, [16] count
   13.39 -    int value_offset  = java_lang_String::value_offset_in_bytes();
   13.40 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
   13.41 -    int count_offset  = java_lang_String::count_offset_in_bytes();
   13.42 -    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
   13.43 -
   13.44 -    masm.load_heap_oop(rax, Address(rsi, value_offset));
   13.45 -    masm.movl(rcx, Address(rsi, offset_offset));
   13.46 -    masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
   13.47 -    masm.load_heap_oop(rbx, Address(rdi, value_offset));
   13.48 -    masm.movl(rcx, Address(rdi, offset_offset));
   13.49 -    masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
   13.50 -
   13.51 -    // Compute the minimum of the string lengths(rsi) and the
   13.52 -    // difference of the string lengths (stack)
   13.53 -
   13.54 -    // do the conditional move stuff
   13.55 -    masm.movl(rdi, Address(rdi, count_offset));
   13.56 -    masm.movl(rsi, Address(rsi, count_offset));
   13.57 -    masm.movl(rcx, rdi);
   13.58 -    masm.subl(rdi, rsi);
   13.59 -    masm.push(rdi);
   13.60 -    masm.cmov(Assembler::lessEqual, rsi, rcx);
   13.61 -
   13.62 -    // Is the minimum length zero?
   13.63 -    masm.bind(RCX_GOOD_LABEL);
   13.64 -    masm.testl(rsi, rsi);
   13.65 -    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
   13.66 -
   13.67 -    // Load first characters
   13.68 -    masm.load_unsigned_short(rcx, Address(rbx, 0));
   13.69 -    masm.load_unsigned_short(rdi, Address(rax, 0));
   13.70 -
   13.71 -    // Compare first characters
   13.72 -    masm.subl(rcx, rdi);
   13.73 -    masm.jcc(Assembler::notZero,  POP_LABEL);
   13.74 -    masm.decrementl(rsi);
   13.75 -    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
   13.76 -
   13.77 -    {
   13.78 -      // Check after comparing first character to see if strings are equivalent
   13.79 -      Label LSkip2;
   13.80 -      // Check if the strings start at same location
   13.81 -      masm.cmpptr(rbx, rax);
   13.82 -      masm.jccb(Assembler::notEqual, LSkip2);
   13.83 -
   13.84 -      // Check if the length difference is zero (from stack)
   13.85 -      masm.cmpl(Address(rsp, 0), 0x0);
   13.86 -      masm.jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
   13.87 -
   13.88 -      // Strings might not be equivalent
   13.89 -      masm.bind(LSkip2);
   13.90 -    }
   13.91 -
   13.92 -    // Advance to next character
   13.93 -    masm.addptr(rax, 2);
   13.94 -    masm.addptr(rbx, 2);
   13.95 -
   13.96 -    if (UseSSE42Intrinsics) {
   13.97 -      // With SSE4.2, use double quad vector compare
   13.98 -      Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
   13.99 -      // Setup to compare 16-byte vectors
  13.100 -      masm.movl(rdi, rsi);
  13.101 -      masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
  13.102 -      masm.andl(rdi, 0x00000007); // rdi holds the tail count
  13.103 -      masm.testl(rsi, rsi);
  13.104 -      masm.jccb(Assembler::zero, COMPARE_TAIL);
  13.105 -
  13.106 -      masm.lea(rax, Address(rax, rsi, Address::times_2));
  13.107 -      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
  13.108 -      masm.negptr(rsi);
  13.109 -
  13.110 -      masm.bind(COMPARE_VECTORS);
  13.111 -      masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
  13.112 -      masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
  13.113 -      masm.pxor(tmp1Reg, tmp2Reg);
  13.114 -      masm.ptest(tmp1Reg, tmp1Reg);
  13.115 -      masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
  13.116 -      masm.addptr(rsi, 8);
  13.117 -      masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  13.118 -      masm.jmpb(COMPARE_TAIL);
  13.119 -
  13.120 -      // Mismatched characters in the vectors
  13.121 -      masm.bind(VECTOR_NOT_EQUAL);
  13.122 -      masm.lea(rax, Address(rax, rsi, Address::times_2));
  13.123 -      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
  13.124 -      masm.movl(rdi, 8);
  13.125 -
  13.126 -      // Compare tail (< 8 chars), or rescan last vectors to
  13.127 -      // find 1st mismatched characters
  13.128 -      masm.bind(COMPARE_TAIL);
  13.129 -      masm.testl(rdi, rdi);
  13.130 -      masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
  13.131 -      masm.movl(rsi, rdi);
  13.132 -      // Fallthru to tail compare
  13.133 -    }
  13.134 -
  13.135 -    // Shift RAX and RBX to the end of the arrays, negate min
  13.136 -    masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
  13.137 -    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
  13.138 -    masm.negptr(rsi);
  13.139 -
  13.140 -    // Compare the rest of the characters
  13.141 -    masm.bind(WHILE_HEAD_LABEL);
  13.142 -    masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
  13.143 -    masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
  13.144 -    masm.subl(rcx, rdi);
  13.145 -    masm.jccb(Assembler::notZero, POP_LABEL);
  13.146 -    masm.increment(rsi);
  13.147 -    masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
  13.148 -
  13.149 -    // Strings are equal up to min length.  Return the length difference.
  13.150 -    masm.bind(LENGTH_DIFF_LABEL);
  13.151 -    masm.pop(rcx);
  13.152 -    masm.jmpb(DONE_LABEL);
  13.153 -
  13.154 -    // Discard the stored length difference
  13.155 -    masm.bind(POP_LABEL);
  13.156 -    masm.addptr(rsp, 8);
  13.157 -
  13.158 -    // That's it
  13.159 -    masm.bind(DONE_LABEL);
  13.160 -  %}
  13.161 -
  13.162 - enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
  13.163 -                        rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{
  13.164 -    // SSE4.2 version
  13.165 -    Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
  13.166 -          SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
  13.167 -    MacroAssembler masm(&cbuf);
  13.168 -
  13.169 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  13.170 -
  13.171 -    // Get the first character position in both strings
  13.172 -    //         [8] char array, [12] offset, [16] count
  13.173 -    int value_offset  = java_lang_String::value_offset_in_bytes();
  13.174 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
  13.175 -    int count_offset  = java_lang_String::count_offset_in_bytes();
  13.176 -    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  13.177 -
  13.178 -    // Get counts for string and substr
  13.179 -    masm.movl(rdx, Address(rsi, count_offset));
  13.180 -    masm.movl(rax, Address(rdi, count_offset));
  13.181 -    // Check for substr count > string count
  13.182 -    masm.cmpl(rax, rdx);
  13.183 -    masm.jcc(Assembler::greater, RET_NEG_ONE);
  13.184 -
  13.185 -    // Start the indexOf operation
  13.186 -    // Get start addr of string
  13.187 -    masm.load_heap_oop(rbx, Address(rsi, value_offset));
  13.188 -    masm.movl(rcx, Address(rsi, offset_offset));
  13.189 -    masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
  13.190 -    masm.push(rsi);
  13.191 -
  13.192 -    // Get start addr of substr
  13.193 -    masm.load_heap_oop(rbx, Address(rdi, value_offset));
  13.194 -    masm.movl(rcx, Address(rdi, offset_offset));
  13.195 -    masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
  13.196 -    masm.push(rdi);
  13.197 -    masm.push(rax);
  13.198 -    masm.jmpb(PREP_FOR_SCAN);
  13.199 -
  13.200 -    // Substr count saved at sp
  13.201 -    // Substr saved at sp+8
  13.202 -    // String saved at sp+16
  13.203 -
  13.204 -    // Prep to load substr for scan
  13.205 -    masm.bind(LOAD_SUBSTR);
  13.206 -    masm.movptr(rdi, Address(rsp, 8));
  13.207 -    masm.movl(rax, Address(rsp, 0));
  13.208 -
  13.209 -    // Load substr
  13.210 -    masm.bind(PREP_FOR_SCAN);
  13.211 -    masm.movdqu(tmp1Reg, Address(rdi, 0));
  13.212 -    masm.addq(rdx, 8);    // prime the loop
  13.213 -    masm.subptr(rsi, 16);
  13.214 -
  13.215 -    // Scan string for substr in 16-byte vectors
  13.216 -    masm.bind(SCAN_TO_SUBSTR);
  13.217 -    masm.subq(rdx, 8);
  13.218 -    masm.addptr(rsi, 16);
  13.219 -    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  13.220 -    masm.jcc(Assembler::above, SCAN_TO_SUBSTR);
  13.221 -    masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND);
  13.222 -
  13.223 -    // Fallthru: found a potential substr
  13.224 -
  13.225 -    //Make sure string is still long enough
  13.226 -    masm.subl(rdx, rcx);
  13.227 -    masm.cmpl(rdx, rax);
  13.228 -    masm.jccb(Assembler::negative, RET_NOT_FOUND);
  13.229 -    // Compute start addr of substr
  13.230 -    masm.lea(rsi, Address(rsi, rcx, Address::times_2));
  13.231 -    masm.movptr(rbx, rsi);
  13.232 -
  13.233 -    // Compare potential substr
  13.234 -    masm.addq(rdx, 8);        // prime the loop
  13.235 -    masm.addq(rax, 8);
  13.236 -    masm.subptr(rsi, 16);
  13.237 -    masm.subptr(rdi, 16);
  13.238 -
  13.239 -    // Scan 16-byte vectors of string and substr
  13.240 -    masm.bind(SCAN_SUBSTR);
  13.241 -    masm.subq(rax, 8);
  13.242 -    masm.subq(rdx, 8);
  13.243 -    masm.addptr(rsi, 16);
  13.244 -    masm.addptr(rdi, 16);
  13.245 -    masm.movdqu(tmp1Reg, Address(rdi, 0));
  13.246 -    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  13.247 -    masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
  13.248 -    masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
  13.249 -
  13.250 -    // Compute substr offset
  13.251 -    masm.movptr(rsi, Address(rsp, 16));
  13.252 -    masm.subptr(rbx, rsi);
  13.253 -    masm.shrl(rbx, 1);
  13.254 -    masm.jmpb(CLEANUP);
  13.255 -
  13.256 -    masm.bind(RET_NEG_ONE);
  13.257 -    masm.movl(rbx, -1);
  13.258 -    masm.jmpb(DONE);
  13.259 -
  13.260 -    masm.bind(RET_NOT_FOUND);
  13.261 -    masm.movl(rbx, -1);
  13.262 -
  13.263 -    masm.bind(CLEANUP);
  13.264 -    masm.addptr(rsp, 24);
  13.265 -
  13.266 -    masm.bind(DONE);
  13.267 -  %}
  13.268 -
  13.269 -  enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
  13.270 -                              rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{
  13.271 -    Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  13.272 -    MacroAssembler masm(&cbuf);
  13.273 -
  13.274 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  13.275 -    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  13.276 -
  13.277 -    int value_offset  = java_lang_String::value_offset_in_bytes();
  13.278 -    int offset_offset = java_lang_String::offset_offset_in_bytes();
  13.279 -    int count_offset  = java_lang_String::count_offset_in_bytes();
  13.280 -    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  13.281 -
  13.282 -    // does source == target string?
  13.283 -    masm.cmpptr(rdi, rsi);
  13.284 -    masm.jcc(Assembler::equal, RET_TRUE);
  13.285 -
  13.286 -    // get and compare counts
  13.287 -    masm.movl(rcx, Address(rdi, count_offset));
  13.288 -    masm.movl(rax, Address(rsi, count_offset));
  13.289 -    masm.cmpl(rcx, rax);
  13.290 -    masm.jcc(Assembler::notEqual, RET_FALSE);
  13.291 -    masm.testl(rax, rax);
  13.292 -    masm.jcc(Assembler::zero, RET_TRUE);
  13.293 -
  13.294 -    // get source string offset and value
  13.295 -    masm.load_heap_oop(rbx, Address(rsi, value_offset));
  13.296 -    masm.movl(rax, Address(rsi, offset_offset));
  13.297 -    masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset));
  13.298 -
  13.299 -    // get compare string offset and value
  13.300 -    masm.load_heap_oop(rbx, Address(rdi, value_offset));
  13.301 -    masm.movl(rax, Address(rdi, offset_offset));
  13.302 -    masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset));
  13.303 -
  13.304 -    // Set byte count
  13.305 -    masm.shll(rcx, 1);
  13.306 -    masm.movl(rax, rcx);
  13.307 -
  13.308 -    if (UseSSE42Intrinsics) {
  13.309 -      // With SSE4.2, use double quad vector compare
  13.310 -      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  13.311 -      // Compare 16-byte vectors
  13.312 -      masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
  13.313 -      masm.andl(rax, 0x0000000e);  // tail count (in bytes)
  13.314 -      masm.testl(rcx, rcx);
  13.315 -      masm.jccb(Assembler::zero, COMPARE_TAIL);
  13.316 -      masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  13.317 -      masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  13.318 -      masm.negptr(rcx);
  13.319 -
  13.320 -      masm.bind(COMPARE_WIDE_VECTORS);
  13.321 -      masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
  13.322 -      masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
  13.323 -      masm.pxor(tmp1Reg, tmp2Reg);
  13.324 -      masm.ptest(tmp1Reg, tmp1Reg);
  13.325 -      masm.jccb(Assembler::notZero, RET_FALSE);
  13.326 -      masm.addptr(rcx, 16);
  13.327 -      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  13.328 -      masm.bind(COMPARE_TAIL);
  13.329 -      masm.movl(rcx, rax);
  13.330 -      // Fallthru to tail compare
  13.331 -    }
  13.332 -
  13.333 -    // Compare 4-byte vectors
  13.334 -    masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
  13.335 -    masm.andl(rax, 0x00000002);  // tail char (in bytes)
  13.336 -    masm.testl(rcx, rcx);
  13.337 -    masm.jccb(Assembler::zero, COMPARE_CHAR);
  13.338 -    masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  13.339 -    masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  13.340 -    masm.negptr(rcx);
  13.341 -
  13.342 -    masm.bind(COMPARE_VECTORS);
  13.343 -    masm.movl(rbx, Address(rdi, rcx, Address::times_1));
  13.344 -    masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
  13.345 -    masm.jccb(Assembler::notEqual, RET_FALSE);
  13.346 -    masm.addptr(rcx, 4);
  13.347 -    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  13.348 -
  13.349 -    // Compare trailing char (final 2 bytes), if any
  13.350 -    masm.bind(COMPARE_CHAR);
  13.351 -    masm.testl(rax, rax);
  13.352 -    masm.jccb(Assembler::zero, RET_TRUE);
  13.353 -    masm.load_unsigned_short(rbx, Address(rdi, 0));
  13.354 -    masm.load_unsigned_short(rcx, Address(rsi, 0));
  13.355 -    masm.cmpl(rbx, rcx);
  13.356 -    masm.jccb(Assembler::notEqual, RET_FALSE);
  13.357 -
  13.358 -    masm.bind(RET_TRUE);
  13.359 -    masm.movl(rax, 1);   // return true
  13.360 -    masm.jmpb(DONE);
  13.361 -
  13.362 -    masm.bind(RET_FALSE);
  13.363 -    masm.xorl(rax, rax); // return false
  13.364 -
  13.365 -    masm.bind(DONE);
  13.366 -  %}
  13.367 -
  13.368 -  enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2,
  13.369 -                             rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
  13.370 -    Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  13.371 -    MacroAssembler masm(&cbuf);
  13.372 -
  13.373 -    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  13.374 -    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  13.375 -    Register ary1Reg      = as_Register($ary1$$reg);
  13.376 -    Register ary2Reg      = as_Register($ary2$$reg);
  13.377 -    Register tmp3Reg      = as_Register($tmp3$$reg);
  13.378 -    Register tmp4Reg      = as_Register($tmp4$$reg);
  13.379 -    Register resultReg    = as_Register($result$$reg);
  13.380 -
  13.381 -    int length_offset  = arrayOopDesc::length_offset_in_bytes();
  13.382 -    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  13.383 -
  13.384 -    // Check the input args
  13.385 -    masm.cmpq(ary1Reg, ary2Reg);
  13.386 -    masm.jcc(Assembler::equal, TRUE_LABEL);
  13.387 -    masm.testq(ary1Reg, ary1Reg);
  13.388 -    masm.jcc(Assembler::zero, FALSE_LABEL);
  13.389 -    masm.testq(ary2Reg, ary2Reg);
  13.390 -    masm.jcc(Assembler::zero, FALSE_LABEL);
  13.391 -
  13.392 -    // Check the lengths
  13.393 -    masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
  13.394 -    masm.movl(resultReg, Address(ary2Reg, length_offset));
  13.395 -    masm.cmpl(tmp4Reg, resultReg);
  13.396 -    masm.jcc(Assembler::notEqual, FALSE_LABEL);
  13.397 -    masm.testl(resultReg, resultReg);
  13.398 -    masm.jcc(Assembler::zero, TRUE_LABEL);
  13.399 -
  13.400 -    //load array address
  13.401 -    masm.lea(ary1Reg, Address(ary1Reg, base_offset));
  13.402 -    masm.lea(ary2Reg, Address(ary2Reg, base_offset));
  13.403 -
  13.404 -    //set byte count
  13.405 -    masm.shll(tmp4Reg, 1);
  13.406 -    masm.movl(resultReg,tmp4Reg);
  13.407 -
  13.408 -    if (UseSSE42Intrinsics){
  13.409 -      // With SSE4.2, use double quad vector compare
  13.410 -      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  13.411 -      // Compare 16-byte vectors
  13.412 -      masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
  13.413 -      masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
  13.414 -      masm.testl(tmp4Reg, tmp4Reg);
  13.415 -      masm.jccb(Assembler::zero, COMPARE_TAIL);
  13.416 -      masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  13.417 -      masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  13.418 -      masm.negptr(tmp4Reg);
  13.419 -
  13.420 -      masm.bind(COMPARE_WIDE_VECTORS);
  13.421 -      masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  13.422 -      masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  13.423 -      masm.pxor(tmp1Reg, tmp2Reg);
  13.424 -      masm.ptest(tmp1Reg, tmp1Reg);
  13.425 -
  13.426 -      masm.jccb(Assembler::notZero, FALSE_LABEL);
  13.427 -      masm.addptr(tmp4Reg, 16);
  13.428 -      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  13.429 -      masm.bind(COMPARE_TAIL);
  13.430 -      masm.movl(tmp4Reg, resultReg);
  13.431 -      // Fallthru to tail compare
  13.432 -    }
  13.433 -
  13.434 -   // Compare 4-byte vectors
  13.435 -    masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
  13.436 -    masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
  13.437 -    masm.testl(tmp4Reg, tmp4Reg); //if tmp2 == 0, only compare char
  13.438 -    masm.jccb(Assembler::zero, COMPARE_CHAR);
  13.439 -    masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  13.440 -    masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  13.441 -    masm.negptr(tmp4Reg);
  13.442 -
  13.443 -    masm.bind(COMPARE_VECTORS);
  13.444 -    masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  13.445 -    masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  13.446 -    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  13.447 -    masm.addptr(tmp4Reg, 4);
  13.448 -    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  13.449 -
  13.450 -    // Compare trailing char (final 2 bytes), if any
  13.451 -    masm.bind(COMPARE_CHAR);
  13.452 -    masm.testl(resultReg, resultReg);
  13.453 -    masm.jccb(Assembler::zero, TRUE_LABEL);
  13.454 -    masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
  13.455 -    masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
  13.456 -    masm.cmpl(tmp3Reg, tmp4Reg);
  13.457 -    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  13.458 -
  13.459 -    masm.bind(TRUE_LABEL);
  13.460 -    masm.movl(resultReg, 1);   // return true
  13.461 -    masm.jmpb(DONE);
  13.462 -
  13.463 -    masm.bind(FALSE_LABEL);
  13.464 -    masm.xorl(resultReg, resultReg); // return false
  13.465 -
  13.466 -    // That's it
  13.467 -    masm.bind(DONE);
  13.468 -  %}
  13.469  
  13.470    enc_class enc_rethrow()
  13.471    %{
  13.472 @@ -12096,52 +11654,67 @@
  13.473    ins_pipe(pipe_slow);
  13.474  %}
  13.475  
  13.476 -instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
  13.477 -                        rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
  13.478 -%{
  13.479 -  match(Set result (StrComp str1 str2));
  13.480 -  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  13.481 -  //ins_cost(300);
  13.482 -
  13.483 -  format %{ "String Compare $str1, $str2 -> $result    // XXX KILL RAX, RBX" %}
  13.484 -  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  13.485 +instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2,
  13.486 +                        rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr)
  13.487 +%{
  13.488 +  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
  13.489 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
  13.490 +
  13.491 +  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
  13.492 +  ins_encode %{
  13.493 +    __ string_compare($str1$$Register, $str2$$Register,
  13.494 +                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
  13.495 +                      $tmp1$$XMMRegister, $tmp2$$XMMRegister);
  13.496 +  %}
  13.497    ins_pipe( pipe_slow );
  13.498  %}
  13.499  
  13.500 -instruct string_indexof(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
  13.501 -                        rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr)
  13.502 +instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
  13.503 +                        rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
  13.504  %{
  13.505    predicate(UseSSE42Intrinsics);
  13.506 -  match(Set result (StrIndexOf str1 str2));
  13.507 -  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
  13.508 -
  13.509 -  format %{ "String IndexOf $str1,$str2 -> $result   // KILL RAX, RCX, RDX" %}
  13.510 -  ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  13.511 +  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
  13.512 +  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
  13.513 +
  13.514 +  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
  13.515 +  ins_encode %{
  13.516 +    __ string_indexof($str1$$Register, $str2$$Register,
  13.517 +                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
  13.518 +                      $tmp1$$XMMRegister, $tmp2$$Register);
  13.519 +  %}
  13.520    ins_pipe( pipe_slow );
  13.521  %}
  13.522  
  13.523  // fast string equals
  13.524 -instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3,
  13.525 -                       rcx_RegI tmp4, rax_RegI result, rFlagsReg cr)
  13.526 -%{
  13.527 -  match(Set result (StrEquals str1 str2));
  13.528 -  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  13.529 -
  13.530 -  format %{ "String Equals $str1,$str2 -> $result    // KILL RBX, RCX" %}
  13.531 -  ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  13.532 +instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
  13.533 +                       regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
  13.534 +%{
  13.535 +  match(Set result (StrEquals (Binary str1 str2) cnt));
  13.536 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
  13.537 +
  13.538 +  format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
  13.539 +  ins_encode %{
  13.540 +    __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
  13.541 +                          $cnt$$Register, $result$$Register, $tmp3$$Register,
  13.542 +                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
  13.543 +  %}
  13.544    ins_pipe( pipe_slow );
  13.545  %}
  13.546  
  13.547  // fast array equals
  13.548 -instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2, rax_RegI tmp3,
  13.549 -                      rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
  13.550 +instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
  13.551 +                      regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
  13.552  %{
  13.553    match(Set result (AryEq ary1 ary2));
  13.554    effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
  13.555    //ins_cost(300);
  13.556  
  13.557 -  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL RAX, RBX" %}
  13.558 -  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
  13.559 +  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
  13.560 +  ins_encode %{
  13.561 +    __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
  13.562 +                          $tmp3$$Register, $result$$Register, $tmp4$$Register,
  13.563 +                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
  13.564 +  %}
  13.565    ins_pipe( pipe_slow );
  13.566  %}
  13.567  
    14.1 --- a/src/share/vm/adlc/formssel.cpp	Fri Oct 02 11:26:25 2009 -0700
    14.2 +++ b/src/share/vm/adlc/formssel.cpp	Fri Oct 09 15:18:52 2009 -0700
    14.3 @@ -828,11 +828,13 @@
    14.4      return AdlcVMDeps::Parms;   // Skip the machine-state edges
    14.5  
    14.6    if( _matrule->_rChild &&
    14.7 -      ( strcmp(_matrule->_rChild->_opType,"StrComp"   )==0 ||
    14.8 +      ( strcmp(_matrule->_rChild->_opType,"AryEq"     )==0 ||
    14.9 +        strcmp(_matrule->_rChild->_opType,"StrComp"   )==0 ||
   14.10          strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
   14.11          strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 )) {
   14.12 -        // String.(compareTo/equals/indexOf) take 1 control and 4 memory edges.
   14.13 -    return 5;
   14.14 +        // String.(compareTo/equals/indexOf) and Arrays.equals
   14.15 +        // take 1 control and 1 memory edges.
   14.16 +    return 2;
   14.17    }
   14.18  
   14.19    // Check for handling of 'Memory' input/edge in the ideal world.
    15.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Oct 02 11:26:25 2009 -0700
    15.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Oct 09 15:18:52 2009 -0700
    15.3 @@ -1442,7 +1442,7 @@
    15.4          switch (field_type) {
    15.5          case T_ARRAY:
    15.6          case T_OBJECT:
    15.7 -          if (field_val.as_object()->has_encoding()) {
    15.8 +          if (field_val.as_object()->should_be_constant()) {
    15.9              constant =  new Constant(as_ValueType(field_val));
   15.10            }
   15.11            break;
    16.1 --- a/src/share/vm/c1/c1_InstructionPrinter.cpp	Fri Oct 02 11:26:25 2009 -0700
    16.2 +++ b/src/share/vm/c1/c1_InstructionPrinter.cpp	Fri Oct 09 15:18:52 2009 -0700
    16.3 @@ -133,12 +133,12 @@
    16.4        ciMethod* m = (ciMethod*)value;
    16.5        output()->print("<method %s.%s>", m->holder()->name()->as_utf8(), m->name()->as_utf8());
    16.6      } else {
    16.7 -      output()->print("<object 0x%x>", value->encoding());
    16.8 +      output()->print("<object 0x%x>", value->constant_encoding());
    16.9      }
   16.10    } else if (type->as_InstanceConstant() != NULL) {
   16.11 -    output()->print("<instance 0x%x>", type->as_InstanceConstant()->value()->encoding());
   16.12 +    output()->print("<instance 0x%x>", type->as_InstanceConstant()->value()->constant_encoding());
   16.13    } else if (type->as_ArrayConstant() != NULL) {
   16.14 -    output()->print("<array 0x%x>", type->as_ArrayConstant()->value()->encoding());
   16.15 +    output()->print("<array 0x%x>", type->as_ArrayConstant()->value()->constant_encoding());
   16.16    } else if (type->as_ClassConstant() != NULL) {
   16.17      ciInstanceKlass* klass = type->as_ClassConstant()->value();
   16.18      if (!klass->is_loaded()) {
    17.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 02 11:26:25 2009 -0700
    17.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 09 15:18:52 2009 -0700
    17.3 @@ -440,7 +440,7 @@
    17.4      __ oop2reg_patch(NULL, r, info);
    17.5    } else {
    17.6      // no patching needed
    17.7 -    __ oop2reg(obj->encoding(), r);
    17.8 +    __ oop2reg(obj->constant_encoding(), r);
    17.9    }
   17.10  }
   17.11  
   17.12 @@ -831,7 +831,7 @@
   17.13      int taken_count_offset     = md->byte_offset_of_slot(data, BranchData::taken_offset());
   17.14      int not_taken_count_offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset());
   17.15      LIR_Opr md_reg = new_register(T_OBJECT);
   17.16 -    __ move(LIR_OprFact::oopConst(md->encoding()), md_reg);
   17.17 +    __ move(LIR_OprFact::oopConst(md->constant_encoding()), md_reg);
   17.18      LIR_Opr data_offset_reg = new_register(T_INT);
   17.19      __ cmove(lir_cond(cond),
   17.20               LIR_OprFact::intConst(taken_count_offset),
   17.21 @@ -1071,7 +1071,7 @@
   17.22      LIR_OprList* args = new LIR_OprList();
   17.23      args->append(getThreadPointer());
   17.24      LIR_Opr meth = new_register(T_OBJECT);
   17.25 -    __ oop2reg(method()->encoding(), meth);
   17.26 +    __ oop2reg(method()->constant_encoding(), meth);
   17.27      args->append(meth);
   17.28      call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
   17.29    }
   17.30 @@ -1784,7 +1784,7 @@
   17.31      LIR_OprList* args = new LIR_OprList();
   17.32      args->append(getThreadPointer());
   17.33      LIR_Opr meth = new_register(T_OBJECT);
   17.34 -    __ oop2reg(method()->encoding(), meth);
   17.35 +    __ oop2reg(method()->constant_encoding(), meth);
   17.36      args->append(meth);
   17.37      call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
   17.38    }
   17.39 @@ -2207,7 +2207,7 @@
   17.40      LIR_OprList* args = new LIR_OprList();
   17.41      args->append(getThreadPointer());
   17.42      LIR_Opr meth = new_register(T_OBJECT);
   17.43 -    __ oop2reg(method()->encoding(), meth);
   17.44 +    __ oop2reg(method()->constant_encoding(), meth);
   17.45      args->append(meth);
   17.46      call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), voidType, NULL);
   17.47    }
   17.48 @@ -2216,7 +2216,7 @@
   17.49      LIR_Opr obj;
   17.50      if (method()->is_static()) {
   17.51        obj = new_register(T_OBJECT);
   17.52 -      __ oop2reg(method()->holder()->java_mirror()->encoding(), obj);
   17.53 +      __ oop2reg(method()->holder()->java_mirror()->constant_encoding(), obj);
   17.54      } else {
   17.55        Local* receiver = x->state()->local_at(0)->as_Local();
   17.56        assert(receiver != NULL, "must already exist");
   17.57 @@ -2660,7 +2660,7 @@
   17.58      }
   17.59  
   17.60      LIR_Opr meth = new_register(T_OBJECT);
   17.61 -    __ oop2reg(method()->encoding(), meth);
   17.62 +    __ oop2reg(method()->constant_encoding(), meth);
   17.63      LIR_Opr result = increment_and_return_counter(meth, offset, InvocationCounter::count_increment);
   17.64      __ cmp(lir_cond_aboveEqual, result, LIR_OprFact::intConst(limit));
   17.65      CodeStub* overflow = new CounterOverflowStub(info, info->bci());
    18.1 --- a/src/share/vm/c1/c1_ValueType.cpp	Fri Oct 02 11:26:25 2009 -0700
    18.2 +++ b/src/share/vm/c1/c1_ValueType.cpp	Fri Oct 09 15:18:52 2009 -0700
    18.3 @@ -86,7 +86,7 @@
    18.4  
    18.5  jobject ObjectType::encoding() const {
    18.6    assert(is_constant(), "must be");
    18.7 -  return constant_value()->encoding();
    18.8 +  return constant_value()->constant_encoding();
    18.9  }
   18.10  
   18.11  bool ObjectType::is_loaded() const {
    19.1 --- a/src/share/vm/ci/ciEnv.cpp	Fri Oct 02 11:26:25 2009 -0700
    19.2 +++ b/src/share/vm/ci/ciEnv.cpp	Fri Oct 09 15:18:52 2009 -0700
    19.3 @@ -257,7 +257,7 @@
    19.4  
    19.5  // ------------------------------------------------------------------
    19.6  // ciEnv::make_array
    19.7 -ciArray* ciEnv::make_array(GrowableArray<ciObject*>* objects) {
    19.8 +ciArray* ciEnv::make_system_array(GrowableArray<ciObject*>* objects) {
    19.9    VM_ENTRY_MARK;
   19.10    int length = objects->length();
   19.11    objArrayOop a = oopFactory::new_system_objArray(length, THREAD);
    20.1 --- a/src/share/vm/ci/ciEnv.hpp	Fri Oct 02 11:26:25 2009 -0700
    20.2 +++ b/src/share/vm/ci/ciEnv.hpp	Fri Oct 09 15:18:52 2009 -0700
    20.3 @@ -339,8 +339,8 @@
    20.4    // but consider adding to vmSymbols.hpp instead.
    20.5  
    20.6    // Use this to make a holder for non-perm compile time constants.
    20.7 -  // The resulting array is guaranteed to satisfy "has_encoding".
    20.8 -  ciArray*  make_array(GrowableArray<ciObject*>* objects);
    20.9 +  // The resulting array is guaranteed to satisfy "can_be_constant".
   20.10 +  ciArray*  make_system_array(GrowableArray<ciObject*>* objects);
   20.11  
   20.12    // converts the ciKlass* representing the holder of a method into a
   20.13    // ciInstanceKlass*.  This is needed since the holder of a method in
    21.1 --- a/src/share/vm/ci/ciMethod.cpp	Fri Oct 02 11:26:25 2009 -0700
    21.2 +++ b/src/share/vm/ci/ciMethod.cpp	Fri Oct 09 15:18:52 2009 -0700
    21.3 @@ -325,10 +325,10 @@
    21.4  }
    21.5  
    21.6  // ------------------------------------------------------------------
    21.7 -// ciMethod::liveness_at_bci
    21.8 +// ciMethod::raw_liveness_at_bci
    21.9  //
   21.10  // Which local variables are live at a specific bci?
   21.11 -MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
   21.12 +MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) {
   21.13    check_is_loaded();
   21.14    if (_liveness == NULL) {
   21.15      // Create the liveness analyzer.
   21.16 @@ -336,7 +336,17 @@
   21.17      _liveness = new (arena) MethodLiveness(arena, this);
   21.18      _liveness->compute_liveness();
   21.19    }
   21.20 -  MethodLivenessResult result = _liveness->get_liveness_at(bci);
   21.21 +  return _liveness->get_liveness_at(bci);
   21.22 +}
   21.23 +
   21.24 +// ------------------------------------------------------------------
   21.25 +// ciMethod::liveness_at_bci
   21.26 +//
   21.27 +// Which local variables are live at a specific bci?  When debugging
   21.28 +// will return true for all locals in some cases to improve debug
   21.29 +// information.
   21.30 +MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
   21.31 +  MethodLivenessResult result = raw_liveness_at_bci(bci);
   21.32    if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
   21.33      // Keep all locals live for the user's edification and amusement.
   21.34      result.at_put_range(0, result.size(), true);
    22.1 --- a/src/share/vm/ci/ciMethod.hpp	Fri Oct 02 11:26:25 2009 -0700
    22.2 +++ b/src/share/vm/ci/ciMethod.hpp	Fri Oct 09 15:18:52 2009 -0700
    22.3 @@ -149,6 +149,12 @@
    22.4    bool          has_monitor_bytecodes() const    { return _uses_monitors; }
    22.5    bool          has_balanced_monitors();
    22.6  
    22.7 +  // Returns a bitmap indicating which locals are required to be
    22.8 +  // maintained as live for deopt.  raw_liveness_at_bci is always the
    22.9 +  // direct output of the liveness computation while liveness_at_bci
   22.10 +  // may mark all locals as live to improve support for debugging Java
   22.11 +  // code by maintaining the state of as many locals as possible.
   22.12 +  MethodLivenessResult raw_liveness_at_bci(int bci);
   22.13    MethodLivenessResult liveness_at_bci(int bci);
   22.14  
   22.15    // Get the interpreters viewpoint on oop liveness.  MethodLiveness is
    23.1 --- a/src/share/vm/ci/ciObject.cpp	Fri Oct 02 11:26:25 2009 -0700
    23.2 +++ b/src/share/vm/ci/ciObject.cpp	Fri Oct 09 15:18:52 2009 -0700
    23.3 @@ -55,6 +55,7 @@
    23.4    }
    23.5    _klass = NULL;
    23.6    _ident = 0;
    23.7 +  init_flags_from(o);
    23.8  }
    23.9  
   23.10  // ------------------------------------------------------------------
   23.11 @@ -69,6 +70,7 @@
   23.12    }
   23.13    _klass = NULL;
   23.14    _ident = 0;
   23.15 +  init_flags_from(h());
   23.16  }
   23.17  
   23.18  // ------------------------------------------------------------------
   23.19 @@ -158,7 +160,7 @@
   23.20  }
   23.21  
   23.22  // ------------------------------------------------------------------
   23.23 -// ciObject::encoding
   23.24 +// ciObject::constant_encoding
   23.25  //
   23.26  // The address which the compiler should embed into the
   23.27  // generated code to represent this oop.  This address
   23.28 @@ -172,16 +174,24 @@
   23.29  //
   23.30  // This method should be changed to return an generified address
   23.31  // to discourage use of the JNI handle.
   23.32 -jobject ciObject::encoding() {
   23.33 +jobject ciObject::constant_encoding() {
   23.34    assert(is_null_object() || handle() != NULL, "cannot embed null pointer");
   23.35 -  assert(has_encoding(), "oop must be NULL or perm");
   23.36 +  assert(can_be_constant(), "oop must be NULL or perm");
   23.37    return handle();
   23.38  }
   23.39  
   23.40  // ------------------------------------------------------------------
   23.41 -// ciObject::has_encoding
   23.42 -bool ciObject::has_encoding() {
   23.43 -  return handle() == NULL || is_perm();
   23.44 +// ciObject::can_be_constant
   23.45 +bool ciObject::can_be_constant() {
   23.46 +  if (ScavengeRootsInCode >= 1)  return true;  // now everybody can encode as a constant
   23.47 +  return handle() == NULL || !is_scavengable();
   23.48 +}
   23.49 +
   23.50 +// ------------------------------------------------------------------
   23.51 +// ciObject::should_be_constant()
   23.52 +bool ciObject::should_be_constant() {
   23.53 +  if (ScavengeRootsInCode >= 2)  return true;  // force everybody to be a constant
   23.54 +  return handle() == NULL || !is_scavengable();
   23.55  }
   23.56  
   23.57  
   23.58 @@ -195,8 +205,9 @@
   23.59  void ciObject::print(outputStream* st) {
   23.60    st->print("<%s", type_string());
   23.61    GUARDED_VM_ENTRY(print_impl(st);)
   23.62 -  st->print(" ident=%d %s address=0x%x>", ident(),
   23.63 +  st->print(" ident=%d %s%s address=0x%x>", ident(),
   23.64          is_perm() ? "PERM" : "",
   23.65 +        is_scavengable() ? "SCAVENGABLE" : "",
   23.66          (address)this);
   23.67  }
   23.68  
    24.1 --- a/src/share/vm/ci/ciObject.hpp	Fri Oct 02 11:26:25 2009 -0700
    24.2 +++ b/src/share/vm/ci/ciObject.hpp	Fri Oct 09 15:18:52 2009 -0700
    24.3 @@ -51,9 +51,10 @@
    24.4    ciKlass* _klass;
    24.5    uint     _ident;
    24.6  
    24.7 -  enum { FLAG_BITS   = 1};
    24.8 +  enum { FLAG_BITS   = 2 };
    24.9    enum {
   24.10 -         PERM_FLAG    = 1
   24.11 +         PERM_FLAG        = 1,
   24.12 +         SCAVENGABLE_FLAG = 2
   24.13         };
   24.14  protected:
   24.15    ciObject();
   24.16 @@ -68,8 +69,15 @@
   24.17      return JNIHandles::resolve_non_null(_handle);
   24.18    }
   24.19  
   24.20 -  void set_perm() {
   24.21 -    _ident |=  PERM_FLAG;
   24.22 +  void init_flags_from(oop x) {
   24.23 +    int flags = 0;
   24.24 +    if (x != NULL) {
   24.25 +      if (x->is_perm())
   24.26 +        flags |= PERM_FLAG;
   24.27 +      if (x->is_scavengable())
   24.28 +        flags |= SCAVENGABLE_FLAG;
   24.29 +    }
   24.30 +    _ident |= flags;
   24.31    }
   24.32  
   24.33    // Virtual behavior of the print() method.
   24.34 @@ -91,17 +99,27 @@
   24.35    // A hash value for the convenience of compilers.
   24.36    int hash();
   24.37  
   24.38 -  // Tells if this oop has an encoding.  (I.e., is it null or perm?)
   24.39 +  // Tells if this oop has an encoding as a constant.
   24.40 +  // True if is_scavengable is false.
   24.41 +  // Also true if ScavengeRootsInCode is non-zero.
   24.42    // If it does not have an encoding, the compiler is responsible for
   24.43    // making other arrangements for dealing with the oop.
   24.44 -  // See ciEnv::make_perm_array
   24.45 -  bool has_encoding();
   24.46 +  // See ciEnv::make_array
   24.47 +  bool can_be_constant();
   24.48 +
   24.49 +  // Tells if this oop should be made a constant.
   24.50 +  // True if is_scavengable is false or ScavengeRootsInCode > 1.
   24.51 +  bool should_be_constant();
   24.52  
   24.53    // Is this object guaranteed to be in the permanent part of the heap?
   24.54    // If so, CollectedHeap::can_elide_permanent_oop_store_barriers is relevant.
   24.55    // If the answer is false, no guarantees are made.
   24.56    bool is_perm() { return (_ident & PERM_FLAG) != 0; }
   24.57  
   24.58 +  // Might this object possibly move during a scavenge operation?
   24.59 +  // If the answer is true and ScavengeRootsInCode==0, the oop cannot be embedded in code.
   24.60 +  bool is_scavengable() { return (_ident & SCAVENGABLE_FLAG) != 0; }
   24.61 +
   24.62    // The address which the compiler should embed into the
   24.63    // generated code to represent this oop.  This address
   24.64    // is not the true address of the oop -- it will get patched
   24.65 @@ -109,7 +127,7 @@
   24.66    //
   24.67    // Usage note: no address arithmetic allowed.  Oop must
   24.68    // be registered with the oopRecorder.
   24.69 -  jobject encoding();
   24.70 +  jobject constant_encoding();
   24.71  
   24.72    // What kind of ciObject is this?
   24.73    virtual bool is_null_object() const       { return false; }
    25.1 --- a/src/share/vm/ci/ciObjectFactory.cpp	Fri Oct 02 11:26:25 2009 -0700
    25.2 +++ b/src/share/vm/ci/ciObjectFactory.cpp	Fri Oct 09 15:18:52 2009 -0700
    25.3 @@ -261,12 +261,11 @@
    25.4      ciObject* new_object = create_new_object(keyHandle());
    25.5      assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
    25.6      init_ident_of(new_object);
    25.7 -    if (!keyHandle->is_perm()) {
    25.8 +    if (!new_object->is_perm()) {
    25.9        // Not a perm-space object.
   25.10        insert_non_perm(bucket, keyHandle(), new_object);
   25.11        return new_object;
   25.12      }
   25.13 -    new_object->set_perm();
   25.14      if (len != _ci_objects->length()) {
   25.15        // creating the new object has recursively entered new objects
   25.16        // into the table.  We need to recompute our index.
    26.1 --- a/src/share/vm/ci/ciTypeFlow.cpp	Fri Oct 02 11:26:25 2009 -0700
    26.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp	Fri Oct 09 15:18:52 2009 -0700
    26.3 @@ -2486,8 +2486,13 @@
    26.4          // Assume irreducible entries need more data flow
    26.5          add_to_work_list(succ);
    26.6        }
    26.7 -      lp = lp->parent();
    26.8 -      assert(lp != NULL, "nested loop must have parent by now");
    26.9 +      Loop* plp = lp->parent();
   26.10 +      if (plp == NULL) {
   26.11 +        // This only happens for some irreducible cases.  The parent
   26.12 +        // will be updated during a later pass.
   26.13 +        break;
   26.14 +      }
   26.15 +      lp = plp;
   26.16      }
   26.17  
   26.18      // Merge loop tree branch for all successors.
    27.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Fri Oct 02 11:26:25 2009 -0700
    27.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Fri Oct 09 15:18:52 2009 -0700
    27.3 @@ -2417,6 +2417,8 @@
    27.4                           vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(),
    27.5                           &args, CHECK_(empty));
    27.6    oop call_site_oop = (oop) result.get_jobject();
    27.7 +  assert(call_site_oop->is_oop()
    27.8 +         /*&& sun_dyn_CallSiteImpl::is_instance(call_site_oop)*/, "must be sane");
    27.9    sun_dyn_CallSiteImpl::set_vmmethod(call_site_oop, mh_invdyn());
   27.10    if (TraceMethodHandles) {
   27.11      tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
   27.12 @@ -2453,6 +2455,8 @@
   27.13    oop boot_method_oop = (oop) result.get_jobject();
   27.14  
   27.15    if (boot_method_oop != NULL) {
   27.16 +    assert(boot_method_oop->is_oop()
   27.17 +           && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
   27.18      // probably no race conditions, but let's be careful:
   27.19      if (Atomic::cmpxchg_ptr(boot_method_oop, ik->adr_bootstrap_method(), NULL) == NULL)
   27.20        ik->set_bootstrap_method(boot_method_oop);
    28.1 --- a/src/share/vm/code/codeBlob.hpp	Fri Oct 02 11:26:25 2009 -0700
    28.2 +++ b/src/share/vm/code/codeBlob.hpp	Fri Oct 09 15:18:52 2009 -0700
    28.3 @@ -175,6 +175,8 @@
    28.4                              OopClosure* keep_alive,
    28.5                              bool unloading_occurred);
    28.6    virtual void oops_do(OopClosure* f) = 0;
    28.7 +  // (All CodeBlob subtypes other than NMethod currently have
    28.8 +  // an empty oops_do() method.
    28.9  
   28.10    // OopMap for frame
   28.11    OopMapSet* oop_maps() const                    { return _oop_maps; }
    29.1 --- a/src/share/vm/code/codeCache.cpp	Fri Oct 02 11:26:25 2009 -0700
    29.2 +++ b/src/share/vm/code/codeCache.cpp	Fri Oct 09 15:18:52 2009 -0700
    29.3 @@ -95,6 +95,7 @@
    29.4  int CodeCache::_number_of_blobs = 0;
    29.5  int CodeCache::_number_of_nmethods_with_dependencies = 0;
    29.6  bool CodeCache::_needs_cache_clean = false;
    29.7 +nmethod* CodeCache::_scavenge_root_nmethods = NULL;
    29.8  
    29.9  
   29.10  CodeBlob* CodeCache::first() {
   29.11 @@ -148,10 +149,7 @@
   29.12      }
   29.13    }
   29.14    verify_if_often();
   29.15 -  if (PrintCodeCache2) {        // Need to add a new flag
   29.16 -      ResourceMark rm;
   29.17 -      tty->print_cr("CodeCache allocation:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, size);
   29.18 -  }
   29.19 +  print_trace("allocation", cb, size);
   29.20    return cb;
   29.21  }
   29.22  
   29.23 @@ -159,10 +157,7 @@
   29.24    assert_locked_or_safepoint(CodeCache_lock);
   29.25    verify_if_often();
   29.26  
   29.27 -  if (PrintCodeCache2) {        // Need to add a new flag
   29.28 -      ResourceMark rm;
   29.29 -      tty->print_cr("CodeCache free:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, cb->size());
   29.30 -  }
   29.31 +  print_trace("free", cb);
   29.32    if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
   29.33      _number_of_nmethods_with_dependencies--;
   29.34    }
   29.35 @@ -260,14 +255,148 @@
   29.36    }
   29.37  }
   29.38  
   29.39 -void CodeCache::oops_do(OopClosure* f) {
   29.40 +void CodeCache::blobs_do(CodeBlobClosure* f) {
   29.41    assert_locked_or_safepoint(CodeCache_lock);
   29.42    FOR_ALL_ALIVE_BLOBS(cb) {
   29.43 -    cb->oops_do(f);
   29.44 +    f->do_code_blob(cb);
   29.45 +
   29.46 +#ifdef ASSERT
   29.47 +    if (cb->is_nmethod())
   29.48 +      ((nmethod*)cb)->verify_scavenge_root_oops();
   29.49 +#endif //ASSERT
   29.50    }
   29.51  }
   29.52  
   29.53 +// Walk the list of methods which might contain non-perm oops.
   29.54 +void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
   29.55 +  assert_locked_or_safepoint(CodeCache_lock);
   29.56 +  debug_only(mark_scavenge_root_nmethods());
   29.57 +
   29.58 +  for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
   29.59 +    debug_only(cur->clear_scavenge_root_marked());
   29.60 +    assert(cur->scavenge_root_not_marked(), "");
   29.61 +    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
   29.62 +
   29.63 +    bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
   29.64 +#ifndef PRODUCT
   29.65 +    if (TraceScavenge) {
   29.66 +      cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
   29.67 +    }
   29.68 +#endif //PRODUCT
   29.69 +    if (is_live)
   29.70 +      // Perform cur->oops_do(f), maybe just once per nmethod.
   29.71 +      f->do_code_blob(cur);
   29.72 +  }
   29.73 +
   29.74 +  // Check for stray marks.
   29.75 +  debug_only(verify_perm_nmethods(NULL));
   29.76 +}
   29.77 +
   29.78 +void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
   29.79 +  assert_locked_or_safepoint(CodeCache_lock);
   29.80 +  nm->set_on_scavenge_root_list();
   29.81 +  nm->set_scavenge_root_link(_scavenge_root_nmethods);
   29.82 +  set_scavenge_root_nmethods(nm);
   29.83 +  print_trace("add_scavenge_root", nm);
   29.84 +}
   29.85 +
   29.86 +void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
   29.87 +  assert_locked_or_safepoint(CodeCache_lock);
   29.88 +  print_trace("drop_scavenge_root", nm);
   29.89 +  nmethod* last = NULL;
   29.90 +  nmethod* cur = scavenge_root_nmethods();
   29.91 +  while (cur != NULL) {
   29.92 +    nmethod* next = cur->scavenge_root_link();
   29.93 +    if (cur == nm) {
   29.94 +      if (last != NULL)
   29.95 +            last->set_scavenge_root_link(next);
   29.96 +      else  set_scavenge_root_nmethods(next);
   29.97 +      nm->set_scavenge_root_link(NULL);
   29.98 +      nm->clear_on_scavenge_root_list();
   29.99 +      return;
  29.100 +    }
  29.101 +    last = cur;
  29.102 +    cur = next;
  29.103 +  }
  29.104 +  assert(false, "should have been on list");
  29.105 +}
  29.106 +
  29.107 +void CodeCache::prune_scavenge_root_nmethods() {
  29.108 +  assert_locked_or_safepoint(CodeCache_lock);
  29.109 +  debug_only(mark_scavenge_root_nmethods());
  29.110 +
  29.111 +  nmethod* last = NULL;
  29.112 +  nmethod* cur = scavenge_root_nmethods();
  29.113 +  while (cur != NULL) {
  29.114 +    nmethod* next = cur->scavenge_root_link();
  29.115 +    debug_only(cur->clear_scavenge_root_marked());
  29.116 +    assert(cur->scavenge_root_not_marked(), "");
  29.117 +    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
  29.118 +
  29.119 +    if (!cur->is_zombie() && !cur->is_unloaded()
  29.120 +        && cur->detect_scavenge_root_oops()) {
  29.121 +      // Keep it.  Advance 'last' to prevent deletion.
  29.122 +      last = cur;
  29.123 +    } else {
  29.124 +      // Prune it from the list, so we don't have to look at it any more.
  29.125 +      print_trace("prune_scavenge_root", cur);
  29.126 +      cur->set_scavenge_root_link(NULL);
  29.127 +      cur->clear_on_scavenge_root_list();
  29.128 +      if (last != NULL)
  29.129 +            last->set_scavenge_root_link(next);
  29.130 +      else  set_scavenge_root_nmethods(next);
  29.131 +    }
  29.132 +    cur = next;
  29.133 +  }
  29.134 +
  29.135 +  // Check for stray marks.
  29.136 +  debug_only(verify_perm_nmethods(NULL));
  29.137 +}
  29.138 +
  29.139 +#ifndef PRODUCT
  29.140 +void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
  29.141 +  // While we are here, verify the integrity of the list.
  29.142 +  mark_scavenge_root_nmethods();
  29.143 +  for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
  29.144 +    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
  29.145 +    cur->clear_scavenge_root_marked();
  29.146 +  }
  29.147 +  verify_perm_nmethods(f);
  29.148 +}
  29.149 +
  29.150 +// Temporarily mark nmethods that are claimed to be on the non-perm list.
  29.151 +void CodeCache::mark_scavenge_root_nmethods() {
  29.152 +  FOR_ALL_ALIVE_BLOBS(cb) {
  29.153 +    if (cb->is_nmethod()) {
  29.154 +      nmethod *nm = (nmethod*)cb;
  29.155 +      assert(nm->scavenge_root_not_marked(), "clean state");
  29.156 +      if (nm->on_scavenge_root_list())
  29.157 +        nm->set_scavenge_root_marked();
  29.158 +    }
  29.159 +  }
  29.160 +}
  29.161 +
  29.162 +// If the closure is given, run it on the unlisted nmethods.
  29.163 +// Also make sure that the effects of mark_scavenge_root_nmethods is gone.
  29.164 +void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
  29.165 +  FOR_ALL_ALIVE_BLOBS(cb) {
  29.166 +    bool call_f = (f_or_null != NULL);
  29.167 +    if (cb->is_nmethod()) {
  29.168 +      nmethod *nm = (nmethod*)cb;
  29.169 +      assert(nm->scavenge_root_not_marked(), "must be already processed");
  29.170 +      if (nm->on_scavenge_root_list())
  29.171 +        call_f = false;  // don't show this one to the client
  29.172 +      nm->verify_scavenge_root_oops();
  29.173 +    } else {
  29.174 +      call_f = false;   // not an nmethod
  29.175 +    }
  29.176 +    if (call_f)  f_or_null->do_code_blob(cb);
  29.177 +  }
  29.178 +}
  29.179 +#endif //PRODUCT
  29.180 +
  29.181  void CodeCache::gc_prologue() {
  29.182 +  assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
  29.183  }
  29.184  
  29.185  
  29.186 @@ -285,6 +414,8 @@
  29.187      cb->fix_oop_relocations();
  29.188    }
  29.189    set_needs_cache_clean(false);
  29.190 +  prune_scavenge_root_nmethods();
  29.191 +  assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
  29.192  }
  29.193  
  29.194  
  29.195 @@ -508,6 +639,14 @@
  29.196    }
  29.197  }
  29.198  
  29.199 +void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
  29.200 +  if (PrintCodeCache2) {  // Need to add a new flag
  29.201 +    ResourceMark rm;
  29.202 +    if (size == 0)  size = cb->size();
  29.203 +    tty->print_cr("CodeCache %s:  addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size);
  29.204 +  }
  29.205 +}
  29.206 +
  29.207  void CodeCache::print_internals() {
  29.208    int nmethodCount = 0;
  29.209    int runtimeStubCount = 0;
    30.1 --- a/src/share/vm/code/codeCache.hpp	Fri Oct 02 11:26:25 2009 -0700
    30.2 +++ b/src/share/vm/code/codeCache.hpp	Fri Oct 09 15:18:52 2009 -0700
    30.3 @@ -45,8 +45,13 @@
    30.4    static int _number_of_blobs;
    30.5    static int _number_of_nmethods_with_dependencies;
    30.6    static bool _needs_cache_clean;
    30.7 +  static nmethod* _scavenge_root_nmethods;  // linked via nm->scavenge_root_link()
    30.8  
    30.9    static void verify_if_often() PRODUCT_RETURN;
   30.10 +
   30.11 +  static void mark_scavenge_root_nmethods() PRODUCT_RETURN;
   30.12 +  static void verify_perm_nmethods(CodeBlobClosure* f_or_null) PRODUCT_RETURN;
   30.13 +
   30.14   public:
   30.15  
   30.16    // Initialization
   30.17 @@ -61,6 +66,7 @@
   30.18    static void flush();                              // flushes all CodeBlobs
   30.19    static bool contains(void *p);                    // returns whether p is included
   30.20    static void blobs_do(void f(CodeBlob* cb));       // iterates over all CodeBlobs
   30.21 +  static void blobs_do(CodeBlobClosure* f);         // iterates over all CodeBlobs
   30.22    static void nmethods_do(void f(nmethod* nm));     // iterates over all nmethods
   30.23  
   30.24    // Lookup
   30.25 @@ -106,12 +112,24 @@
   30.26    static void do_unloading(BoolObjectClosure* is_alive,
   30.27                             OopClosure* keep_alive,
   30.28                             bool unloading_occurred);
   30.29 -  static void oops_do(OopClosure* f);
   30.30 +  static void oops_do(OopClosure* f) {
   30.31 +    CodeBlobToOopClosure oopc(f, /*do_marking=*/ false);
   30.32 +    blobs_do(&oopc);
   30.33 +  }
   30.34 +  static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN;
   30.35 +  static void scavenge_root_nmethods_do(CodeBlobClosure* f);
   30.36 +
   30.37 +  static nmethod* scavenge_root_nmethods()          { return _scavenge_root_nmethods; }
   30.38 +  static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; }
   30.39 +  static void add_scavenge_root_nmethod(nmethod* nm);
   30.40 +  static void drop_scavenge_root_nmethod(nmethod* nm);
   30.41 +  static void prune_scavenge_root_nmethods();
   30.42  
   30.43    // Printing/debugging
   30.44    static void print()   PRODUCT_RETURN;          // prints summary
   30.45    static void print_internals();
   30.46    static void verify();                          // verifies the code cache
   30.47 +  static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
   30.48  
   30.49    // The full limits of the codeCache
   30.50    static address  low_bound()                    { return (address) _heap->low_boundary(); }
    31.1 --- a/src/share/vm/code/debugInfoRec.cpp	Fri Oct 02 11:26:25 2009 -0700
    31.2 +++ b/src/share/vm/code/debugInfoRec.cpp	Fri Oct 09 15:18:52 2009 -0700
    31.3 @@ -299,7 +299,7 @@
    31.4    stream()->write_int(sender_stream_offset);
    31.5  
    31.6    // serialize scope
    31.7 -  jobject method_enc = (method == NULL)? NULL: method->encoding();
    31.8 +  jobject method_enc = (method == NULL)? NULL: method->constant_encoding();
    31.9    stream()->write_int(oop_recorder()->find_index(method_enc));
   31.10    stream()->write_bci(bci);
   31.11    assert(method == NULL ||
    32.1 --- a/src/share/vm/code/dependencies.cpp	Fri Oct 02 11:26:25 2009 -0700
    32.2 +++ b/src/share/vm/code/dependencies.cpp	Fri Oct 09 15:18:52 2009 -0700
    32.3 @@ -302,7 +302,7 @@
    32.4        bytes.write_byte(code_byte);
    32.5        for (int j = 0; j < stride; j++) {
    32.6          if (j == skipj)  continue;
    32.7 -        bytes.write_int(_oop_recorder->find_index(deps->at(i+j)->encoding()));
    32.8 +        bytes.write_int(_oop_recorder->find_index(deps->at(i+j)->constant_encoding()));
    32.9        }
   32.10      }
   32.11    }
    33.1 --- a/src/share/vm/code/nmethod.cpp	Fri Oct 02 11:26:25 2009 -0700
    33.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Oct 09 15:18:52 2009 -0700
    33.3 @@ -581,10 +581,13 @@
    33.4      debug_only(No_Safepoint_Verifier nsv;)
    33.5      assert_locked_or_safepoint(CodeCache_lock);
    33.6  
    33.7 -    NOT_PRODUCT(_has_debug_info = false; )
    33.8 +    NOT_PRODUCT(_has_debug_info = false);
    33.9 +    _oops_do_mark_link       = NULL;
   33.10      _method                  = method;
   33.11      _entry_bci               = InvocationEntryBci;
   33.12 -    _link                    = NULL;
   33.13 +    _osr_link                = NULL;
   33.14 +    _scavenge_root_link      = NULL;
   33.15 +    _scavenge_root_state     = 0;
   33.16      _compiler                = NULL;
   33.17      // We have no exception handler or deopt handler make the
   33.18      // values something that will never match a pc like the nmethod vtable entry
   33.19 @@ -618,7 +621,7 @@
   33.20      _stack_traversal_mark    = 0;
   33.21  
   33.22      code_buffer->copy_oops_to(this);
   33.23 -    debug_only(check_store();)
   33.24 +    debug_only(verify_scavenge_root_oops());
   33.25      CodeCache::commit(this);
   33.26      VTune::create_nmethod(this);
   33.27    }
   33.28 @@ -668,10 +671,13 @@
   33.29      debug_only(No_Safepoint_Verifier nsv;)
   33.30      assert_locked_or_safepoint(CodeCache_lock);
   33.31  
   33.32 -    NOT_PRODUCT(_has_debug_info = false; )
   33.33 +    NOT_PRODUCT(_has_debug_info = false);
   33.34 +    _oops_do_mark_link       = NULL;
   33.35      _method                  = method;
   33.36      _entry_bci               = InvocationEntryBci;
   33.37 -    _link                    = NULL;
   33.38 +    _osr_link                = NULL;
   33.39 +    _scavenge_root_link      = NULL;
   33.40 +    _scavenge_root_state     = 0;
   33.41      _compiler                = NULL;
   33.42      // We have no exception handler or deopt handler make the
   33.43      // values something that will never match a pc like the nmethod vtable entry
   33.44 @@ -703,7 +709,7 @@
   33.45      _stack_traversal_mark    = 0;
   33.46  
   33.47      code_buffer->copy_oops_to(this);
   33.48 -    debug_only(check_store();)
   33.49 +    debug_only(verify_scavenge_root_oops());
   33.50      CodeCache::commit(this);
   33.51      VTune::create_nmethod(this);
   33.52    }
   33.53 @@ -770,12 +776,15 @@
   33.54      debug_only(No_Safepoint_Verifier nsv;)
   33.55      assert_locked_or_safepoint(CodeCache_lock);
   33.56  
   33.57 -    NOT_PRODUCT(_has_debug_info = false; )
   33.58 +    NOT_PRODUCT(_has_debug_info = false);
   33.59 +    _oops_do_mark_link       = NULL;
   33.60      _method                  = method;
   33.61      _compile_id              = compile_id;
   33.62      _comp_level              = comp_level;
   33.63      _entry_bci               = entry_bci;
   33.64 -    _link                    = NULL;
   33.65 +    _osr_link                = NULL;
   33.66 +    _scavenge_root_link      = NULL;
   33.67 +    _scavenge_root_state     = 0;
   33.68      _compiler                = compiler;
   33.69      _orig_pc_offset          = orig_pc_offset;
   33.70  #ifdef HAVE_DTRACE_H
   33.71 @@ -813,7 +822,10 @@
   33.72      code_buffer->copy_oops_to(this);
   33.73      debug_info->copy_to(this);
   33.74      dependencies->copy_to(this);
   33.75 -    debug_only(check_store();)
   33.76 +    if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
   33.77 +      CodeCache::add_scavenge_root_nmethod(this);
   33.78 +    }
   33.79 +    debug_only(verify_scavenge_root_oops());
   33.80  
   33.81      CodeCache::commit(this);
   33.82  
   33.83 @@ -902,23 +914,30 @@
   33.84    if (st != NULL) {
   33.85      ttyLocker ttyl;
   33.86      // Print a little tag line that looks like +PrintCompilation output:
   33.87 -    st->print("%3d%c  %s",
   33.88 +    int tlen = (int) strlen(title);
   33.89 +    bool do_nl = false;
   33.90 +    if (tlen > 0 && title[tlen-1] == '\n') { tlen--; do_nl = true; }
   33.91 +    st->print("%3d%c  %.*s",
   33.92                compile_id(),
   33.93                is_osr_method() ? '%' :
   33.94                method() != NULL &&
   33.95                is_native_method() ? 'n' : ' ',
   33.96 -              title);
   33.97 +              tlen, title);
   33.98  #ifdef TIERED
   33.99      st->print(" (%d) ", comp_level());
  33.100  #endif // TIERED
  33.101      if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
  33.102 -    if (method() != NULL) {
  33.103 -      method()->print_short_name(st);
  33.104 +    if (Universe::heap()->is_gc_active() && method() != NULL) {
  33.105 +      st->print("(method)");
  33.106 +    } else if (method() != NULL) {
  33.107 +        method()->print_short_name(st);
  33.108        if (is_osr_method())
  33.109          st->print(" @ %d", osr_entry_bci());
  33.110        if (method()->code_size() > 0)
  33.111          st->print(" (%d bytes)", method()->code_size());
  33.112      }
  33.113 +
  33.114 +    if (do_nl)  st->cr();
  33.115    }
  33.116  }
  33.117  
  33.118 @@ -1033,6 +1052,7 @@
  33.119    }
  33.120  }
  33.121  
  33.122 +// This is a private interface with the sweeper.
  33.123  void nmethod::mark_as_seen_on_stack() {
  33.124    assert(is_not_entrant(), "must be a non-entrant method");
  33.125    set_stack_traversal_mark(NMethodSweeper::traversal_count());
  33.126 @@ -1077,7 +1097,8 @@
  33.127                    " unloadable], methodOop(" INTPTR_FORMAT
  33.128                    "), cause(" INTPTR_FORMAT ")",
  33.129                    this, (address)_method, (address)cause);
  33.130 -    cause->klass()->print();
  33.131 +    if (!Universe::heap()->is_gc_active())
  33.132 +      cause->klass()->print();
  33.133    }
  33.134    // Unlink the osr method, so we do not look this up again
  33.135    if (is_osr_method()) {
  33.136 @@ -1109,7 +1130,8 @@
  33.137    // The methodOop is gone at this point
  33.138    assert(_method == NULL, "Tautology");
  33.139  
  33.140 -  set_link(NULL);
  33.141 +  set_osr_link(NULL);
  33.142 +  //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
  33.143    NMethodSweeper::notify(this);
  33.144  }
  33.145  
  33.146 @@ -1295,6 +1317,10 @@
  33.147      ec = next;
  33.148    }
  33.149  
  33.150 +  if (on_scavenge_root_list()) {
  33.151 +    CodeCache::drop_scavenge_root_nmethod(this);
  33.152 +  }
  33.153 +
  33.154    ((CodeBlob*)(this))->flush();
  33.155  
  33.156    CodeCache::free(this);
  33.157 @@ -1354,7 +1380,10 @@
  33.158        return false;
  33.159      }
  33.160    }
  33.161 -  assert(unloading_occurred, "Inconsistency in unloading");
  33.162 +  // If ScavengeRootsInCode is true, an nmethod might be unloaded
  33.163 +  // simply because one of its constant oops has gone dead.
  33.164 +  // No actual classes need to be unloaded in order for this to occur.
  33.165 +  assert(unloading_occurred || ScavengeRootsInCode, "Inconsistency in unloading");
  33.166    make_unloaded(is_alive, obj);
  33.167    return true;
  33.168  }
  33.169 @@ -1529,13 +1558,12 @@
  33.170  // the (strong) marking phase, and then again when walking
  33.171  // the code cache contents during the weak roots processing
  33.172  // phase. The two uses are distinguished by means of the
  33.173 -// do_nmethods() method in the closure "f" below -- which
  33.174 -// answers "yes" in the first case, and "no" in the second
  33.175 +// 'do_strong_roots_only' flag, which is true in the first
  33.176  // case. We want to walk the weak roots in the nmethod
  33.177  // only in the second case. The weak roots in the nmethod
  33.178  // are the oops in the ExceptionCache and the InlineCache
  33.179  // oops.
  33.180 -void nmethod::oops_do(OopClosure* f) {
  33.181 +void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only) {
  33.182    // make sure the oops ready to receive visitors
  33.183    assert(!is_zombie() && !is_unloaded(),
  33.184           "should not call follow on zombie or unloaded nmethod");
  33.185 @@ -1553,7 +1581,7 @@
  33.186  
  33.187    // Compiled code
  33.188    f->do_oop((oop*) &_method);
  33.189 -  if (!f->do_nmethods()) {
  33.190 +  if (!do_strong_roots_only) {
  33.191      // weak roots processing phase -- update ExceptionCache oops
  33.192      ExceptionCache* ec = exception_cache();
  33.193      while(ec != NULL) {
  33.194 @@ -1579,12 +1607,108 @@
  33.195    }
  33.196  
  33.197    // Scopes
  33.198 +  // This includes oop constants not inlined in the code stream.
  33.199    for (oop* p = oops_begin(); p < oops_end(); p++) {
  33.200      if (*p == Universe::non_oop_word())  continue;  // skip non-oops
  33.201      f->do_oop(p);
  33.202    }
  33.203  }
  33.204  
  33.205 +#define NMETHOD_SENTINEL ((nmethod*)badAddress)
  33.206 +
  33.207 +nmethod* volatile nmethod::_oops_do_mark_nmethods;
  33.208 +
  33.209 +// An nmethod is "marked" if its _mark_link is set non-null.
  33.210 +// Even if it is the end of the linked list, it will have a non-null link value,
  33.211 +// as long as it is on the list.
  33.212 +// This code must be MP safe, because it is used from parallel GC passes.
  33.213 +bool nmethod::test_set_oops_do_mark() {
  33.214 +  assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
  33.215 +  nmethod* observed_mark_link = _oops_do_mark_link;
  33.216 +  if (observed_mark_link == NULL) {
  33.217 +    // Claim this nmethod for this thread to mark.
  33.218 +    observed_mark_link = (nmethod*)
  33.219 +      Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_link, NULL);
  33.220 +    if (observed_mark_link == NULL) {
  33.221 +
  33.222 +      // Atomically append this nmethod (now claimed) to the head of the list:
  33.223 +      nmethod* observed_mark_nmethods = _oops_do_mark_nmethods;
  33.224 +      for (;;) {
  33.225 +        nmethod* required_mark_nmethods = observed_mark_nmethods;
  33.226 +        _oops_do_mark_link = required_mark_nmethods;
  33.227 +        observed_mark_nmethods = (nmethod*)
  33.228 +          Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods);
  33.229 +        if (observed_mark_nmethods == required_mark_nmethods)
  33.230 +          break;
  33.231 +      }
  33.232 +      // Mark was clear when we first saw this guy.
  33.233 +      NOT_PRODUCT(if (TraceScavenge)  print_on(tty, "oops_do, mark\n"));
  33.234 +      return false;
  33.235 +    }
  33.236 +  }
  33.237 +  // On fall through, another racing thread marked this nmethod before we did.
  33.238 +  return true;
  33.239 +}
  33.240 +
  33.241 +void nmethod::oops_do_marking_prologue() {
  33.242 +  NOT_PRODUCT(if (TraceScavenge)  tty->print_cr("[oops_do_marking_prologue"));
  33.243 +  assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
  33.244 +  // We use cmpxchg_ptr instead of regular assignment here because the user
  33.245 +  // may fork a bunch of threads, and we need them all to see the same state.
  33.246 +  void* observed = Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, NULL);
  33.247 +  guarantee(observed == NULL, "no races in this sequential code");
  33.248 +}
  33.249 +
  33.250 +void nmethod::oops_do_marking_epilogue() {
  33.251 +  assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row");
  33.252 +  nmethod* cur = _oops_do_mark_nmethods;
  33.253 +  while (cur != NMETHOD_SENTINEL) {
  33.254 +    assert(cur != NULL, "not NULL-terminated");
  33.255 +    nmethod* next = cur->_oops_do_mark_link;
  33.256 +    cur->_oops_do_mark_link = NULL;
  33.257 +    NOT_PRODUCT(if (TraceScavenge)  cur->print_on(tty, "oops_do, unmark\n"));
  33.258 +    cur = next;
  33.259 +  }
  33.260 +  void* required = _oops_do_mark_nmethods;
  33.261 +  void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required);
  33.262 +  guarantee(observed == required, "no races in this sequential code");
  33.263 +  NOT_PRODUCT(if (TraceScavenge)  tty->print_cr("oops_do_marking_epilogue]"));
  33.264 +}
  33.265 +
  33.266 +class DetectScavengeRoot: public OopClosure {
  33.267 +  bool     _detected_scavenge_root;
  33.268 +public:
  33.269 +  DetectScavengeRoot() : _detected_scavenge_root(false)
  33.270 +  { NOT_PRODUCT(_print_nm = NULL); }
  33.271 +  bool detected_scavenge_root() { return _detected_scavenge_root; }
  33.272 +  virtual void do_oop(oop* p) {
  33.273 +    if ((*p) != NULL && (*p)->is_scavengable()) {
  33.274 +      NOT_PRODUCT(maybe_print(p));
  33.275 +      _detected_scavenge_root = true;
  33.276 +    }
  33.277 +  }
  33.278 +  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
  33.279 +
  33.280 +#ifndef PRODUCT
  33.281 +  nmethod* _print_nm;
  33.282 +  void maybe_print(oop* p) {
  33.283 +    if (_print_nm == NULL)  return;
  33.284 +    if (!_detected_scavenge_root)  _print_nm->print_on(tty, "new scavenge root");
  33.285 +    tty->print_cr(""PTR_FORMAT"[offset=%d] detected non-perm oop "PTR_FORMAT" (found at "PTR_FORMAT")",
  33.286 +                  _print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
  33.287 +                  (intptr_t)(*p), (intptr_t)p);
  33.288 +    (*p)->print();
  33.289 +  }
  33.290 +#endif //PRODUCT
  33.291 +};
  33.292 +
  33.293 +bool nmethod::detect_scavenge_root_oops() {
  33.294 +  DetectScavengeRoot detect_scavenge_root;
  33.295 +  NOT_PRODUCT(if (TraceScavenge)  detect_scavenge_root._print_nm = this);
  33.296 +  oops_do(&detect_scavenge_root);
  33.297 +  return detect_scavenge_root.detected_scavenge_root();
  33.298 +}
  33.299 +
  33.300  // Method that knows how to preserve outgoing arguments at call. This method must be
  33.301  // called with a frame corresponding to a Java invoke
  33.302  void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
  33.303 @@ -1899,6 +2023,24 @@
  33.304  // -----------------------------------------------------------------------------
  33.305  // Verification
  33.306  
  33.307 +class VerifyOopsClosure: public OopClosure {
  33.308 +  nmethod* _nm;
  33.309 +  bool     _ok;
  33.310 +public:
  33.311 +  VerifyOopsClosure(nmethod* nm) : _nm(nm), _ok(true) { }
  33.312 +  bool ok() { return _ok; }
  33.313 +  virtual void do_oop(oop* p) {
  33.314 +    if ((*p) == NULL || (*p)->is_oop())  return;
  33.315 +    if (_ok) {
  33.316 +      _nm->print_nmethod(true);
  33.317 +      _ok = false;
  33.318 +    }
  33.319 +    tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
  33.320 +                  (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
  33.321 +  }
  33.322 +  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
  33.323 +};
  33.324 +
  33.325  void nmethod::verify() {
  33.326  
  33.327    // Hmm. OSR methods can be deopted but not marked as zombie or not_entrant
  33.328 @@ -1932,6 +2074,11 @@
  33.329      }
  33.330    }
  33.331  
  33.332 +  VerifyOopsClosure voc(this);
  33.333 +  oops_do(&voc);
  33.334 +  assert(voc.ok(), "embedded oops must be OK");
  33.335 +  verify_scavenge_root_oops();
  33.336 +
  33.337    verify_scopes();
  33.338  }
  33.339  
  33.340 @@ -1995,19 +2142,34 @@
  33.341  // Non-product code
  33.342  #ifndef PRODUCT
  33.343  
  33.344 -void nmethod::check_store() {
  33.345 -  // Make sure all oops in the compiled code are tenured
  33.346 +class DebugScavengeRoot: public OopClosure {
  33.347 +  nmethod* _nm;
  33.348 +  bool     _ok;
  33.349 +public:
  33.350 +  DebugScavengeRoot(nmethod* nm) : _nm(nm), _ok(true) { }
  33.351 +  bool ok() { return _ok; }
  33.352 +  virtual void do_oop(oop* p) {
  33.353 +    if ((*p) == NULL || !(*p)->is_scavengable())  return;
  33.354 +    if (_ok) {
  33.355 +      _nm->print_nmethod(true);
  33.356 +      _ok = false;
  33.357 +    }
  33.358 +    tty->print_cr("*** non-perm oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
  33.359 +                  (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
  33.360 +    (*p)->print();
  33.361 +  }
  33.362 +  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
  33.363 +};
  33.364  
  33.365 -  RelocIterator iter(this);
  33.366 -  while (iter.next()) {
  33.367 -    if (iter.type() == relocInfo::oop_type) {
  33.368 -      oop_Relocation* reloc = iter.oop_reloc();
  33.369 -      oop obj = reloc->oop_value();
  33.370 -      if (obj != NULL && !obj->is_perm()) {
  33.371 -        fatal("must be permanent oop in compiled code");
  33.372 -      }
  33.373 -    }
  33.374 +void nmethod::verify_scavenge_root_oops() {
  33.375 +  if (!on_scavenge_root_list()) {
  33.376 +    // Actually look inside, to verify the claim that it's clean.
  33.377 +    DebugScavengeRoot debug_scavenge_root(this);
  33.378 +    oops_do(&debug_scavenge_root);
  33.379 +    if (!debug_scavenge_root.ok())
  33.380 +      fatal("found an unadvertised bad non-perm oop in the code cache");
  33.381    }
  33.382 +  assert(scavenge_root_not_marked(), "");
  33.383  }
  33.384  
  33.385  #endif // PRODUCT
  33.386 @@ -2040,6 +2202,7 @@
  33.387      if (is_not_entrant()) tty->print("not_entrant ");
  33.388      if (is_zombie())      tty->print("zombie ");
  33.389      if (is_unloaded())    tty->print("unloaded ");
  33.390 +    if (on_scavenge_root_list())  tty->print("scavenge_root ");
  33.391      tty->print_cr("}:");
  33.392    }
  33.393    if (size              () > 0) tty->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
    34.1 --- a/src/share/vm/code/nmethod.hpp	Fri Oct 02 11:26:25 2009 -0700
    34.2 +++ b/src/share/vm/code/nmethod.hpp	Fri Oct 09 15:18:52 2009 -0700
    34.3 @@ -125,6 +125,7 @@
    34.4  class nmethod : public CodeBlob {
    34.5    friend class VMStructs;
    34.6    friend class NMethodSweeper;
    34.7 +  friend class CodeCache;  // non-perm oops
    34.8   private:
    34.9    // Shared fields for all nmethod's
   34.10    static int _zombie_instruction_size;
   34.11 @@ -132,7 +133,12 @@
   34.12    methodOop _method;
   34.13    int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   34.14  
   34.15 -  nmethod*  _link;             // To support simple linked-list chaining of nmethods
   34.16 +  // To support simple linked-list chaining of nmethods:
   34.17 +  nmethod*  _osr_link;         // from instanceKlass::osr_nmethods_head
   34.18 +  nmethod*  _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
   34.19 +
   34.20 +  static nmethod* volatile _oops_do_mark_nmethods;
   34.21 +  nmethod*        volatile _oops_do_mark_link;
   34.22  
   34.23    AbstractCompiler* _compiler; // The compiler which compiled this nmethod
   34.24  
   34.25 @@ -174,6 +180,8 @@
   34.26    // used by jvmti to track if an unload event has been posted for this nmethod.
   34.27    bool _unload_reported;
   34.28  
   34.29 +  jbyte _scavenge_root_state;
   34.30 +
   34.31    NOT_PRODUCT(bool _has_debug_info; )
   34.32  
   34.33    // Nmethod Flushing lock (if non-zero, then the nmethod is not removed)
   34.34 @@ -242,7 +250,6 @@
   34.35  
   34.36    // helper methods
   34.37    void* operator new(size_t size, int nmethod_size);
   34.38 -  void check_store();
   34.39  
   34.40    const char* reloc_string_for(u_char* begin, u_char* end);
   34.41    void make_not_entrant_or_zombie(int state);
   34.42 @@ -406,6 +413,24 @@
   34.43    int   version() const                           { return flags.version; }
   34.44    void  set_version(int v);
   34.45  
   34.46 +  // Non-perm oop support
   34.47 +  bool  on_scavenge_root_list() const                  { return (_scavenge_root_state & 1) != 0; }
   34.48 + protected:
   34.49 +  enum { npl_on_list = 0x01, npl_marked = 0x10 };
   34.50 +  void  set_on_scavenge_root_list()                    { _scavenge_root_state = npl_on_list; }
   34.51 +  void  clear_on_scavenge_root_list()                  { _scavenge_root_state = 0; }
   34.52 +  // assertion-checking and pruning logic uses the bits of _scavenge_root_state
   34.53 +#ifndef PRODUCT
   34.54 +  void  set_scavenge_root_marked()                     { _scavenge_root_state |= npl_marked; }
   34.55 +  void  clear_scavenge_root_marked()                   { _scavenge_root_state &= ~npl_marked; }
   34.56 +  bool  scavenge_root_not_marked()                     { return (_scavenge_root_state &~ npl_on_list) == 0; }
   34.57 +  // N.B. there is no positive marked query, and we only use the not_marked query for asserts.
   34.58 +#endif //PRODUCT
   34.59 +  nmethod* scavenge_root_link() const                  { return _scavenge_root_link; }
   34.60 +  void     set_scavenge_root_link(nmethod *n)          { _scavenge_root_link = n; }
   34.61 +
   34.62 + public:
   34.63 +
   34.64    // Sweeper support
   34.65    long  stack_traversal_mark()                    { return _stack_traversal_mark; }
   34.66    void  set_stack_traversal_mark(long l)          { _stack_traversal_mark = l; }
   34.67 @@ -424,8 +449,8 @@
   34.68    int   osr_entry_bci() const                     { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; }
   34.69    address  osr_entry() const                      { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; }
   34.70    void  invalidate_osr_method();
   34.71 -  nmethod* link() const                           { return _link; }
   34.72 -  void     set_link(nmethod *n)                   { _link = n; }
   34.73 +  nmethod* osr_link() const                       { return _osr_link; }
   34.74 +  void     set_osr_link(nmethod *n)               { _osr_link = n; }
   34.75  
   34.76    // tells whether frames described by this nmethod can be deoptimized
   34.77    // note: native wrappers cannot be deoptimized.
   34.78 @@ -465,7 +490,16 @@
   34.79  
   34.80    void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
   34.81                                       OopClosure* f);
   34.82 -  void oops_do(OopClosure* f);
   34.83 +  virtual void oops_do(OopClosure* f) { oops_do(f, false); }
   34.84 +  void         oops_do(OopClosure* f, bool do_strong_roots_only);
   34.85 +  bool detect_scavenge_root_oops();
   34.86 +  void verify_scavenge_root_oops() PRODUCT_RETURN;
   34.87 +
   34.88 +  bool test_set_oops_do_mark();
   34.89 +  static void oops_do_marking_prologue();
   34.90 +  static void oops_do_marking_epilogue();
   34.91 +  static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; }
   34.92 +  DEBUG_ONLY(bool test_oops_do_mark() { return _oops_do_mark_link != NULL; })
   34.93  
   34.94    // ScopeDesc for an instruction
   34.95    ScopeDesc* scope_desc_at(address pc);
    35.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Fri Oct 02 11:26:25 2009 -0700
    35.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Fri Oct 09 15:18:52 2009 -0700
    35.3 @@ -47,20 +47,15 @@
    35.4   private:
    35.5    const MemRegion _span;
    35.6    CMSBitMap*      _bitMap;
    35.7 -  const bool      _should_do_nmethods;
    35.8   protected:
    35.9    DO_OOP_WORK_DEFN
   35.10   public:
   35.11 -  MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap,
   35.12 -                      bool should_do_nmethods);
   35.13 +  MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
   35.14    virtual void do_oop(oop* p);
   35.15    virtual void do_oop(narrowOop* p);
   35.16    inline void do_oop_nv(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
   35.17    inline void do_oop_nv(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
   35.18    bool do_header() { return true; }
   35.19 -  virtual const bool do_nmethods() const {
   35.20 -    return _should_do_nmethods;
   35.21 -  }
   35.22    Prefetch::style prefetch_style() {
   35.23      return Prefetch::do_read;
   35.24    }
   35.25 @@ -73,20 +68,16 @@
   35.26    const MemRegion _span;
   35.27    CMSBitMap*      _verification_bm;
   35.28    CMSBitMap*      _cms_bm;
   35.29 -  const bool      _should_do_nmethods;
   35.30   protected:
   35.31    DO_OOP_WORK_DEFN
   35.32   public:
   35.33    MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
   35.34 -                            CMSBitMap* cms_bm, bool should_do_nmethods);
   35.35 +                            CMSBitMap* cms_bm);
   35.36    virtual void do_oop(oop* p);
   35.37    virtual void do_oop(narrowOop* p);
   35.38    inline void do_oop_nv(oop* p)       { MarkRefsIntoVerifyClosure::do_oop_work(p); }
   35.39    inline void do_oop_nv(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
   35.40    bool do_header() { return true; }
   35.41 -  virtual const bool do_nmethods() const {
   35.42 -    return _should_do_nmethods;
   35.43 -  }
   35.44    Prefetch::style prefetch_style() {
   35.45      return Prefetch::do_read;
   35.46    }
   35.47 @@ -228,7 +219,6 @@
   35.48    inline void do_oop_nv(oop* p)       { MarkRefsIntoAndScanClosure::do_oop_work(p); }
   35.49    inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
   35.50    bool do_header() { return true; }
   35.51 -  virtual const bool do_nmethods() const { return true; }
   35.52    Prefetch::style prefetch_style() {
   35.53      return Prefetch::do_read;
   35.54    }
   35.55 @@ -273,7 +263,6 @@
   35.56    inline void do_oop_nv(oop* p)       { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
   35.57    inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
   35.58    bool do_header() { return true; }
   35.59 -  virtual const bool do_nmethods() const { return true; }
   35.60    // When ScanMarkedObjectsAgainClosure is used,
   35.61    // it passes [Par_]MarkRefsIntoAndScanClosure to oop_oop_iterate(),
   35.62    // and this delegation is used.
    36.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Oct 02 11:26:25 2009 -0700
    36.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Oct 09 15:18:52 2009 -0700
    36.3 @@ -2852,14 +2852,17 @@
    36.4    GenCollectedHeap* gch = GenCollectedHeap::heap();
    36.5  
    36.6    // Mark from roots one level into CMS
    36.7 -  MarkRefsIntoClosure notOlder(_span, verification_mark_bm(), true /* nmethods */);
    36.8 +  MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
    36.9    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
   36.10  
   36.11    gch->gen_process_strong_roots(_cmsGen->level(),
   36.12                                  true,   // younger gens are roots
   36.13 +                                true,   // activate StrongRootsScope
   36.14                                  true,   // collecting perm gen
   36.15                                  SharedHeap::ScanningOption(roots_scanning_options()),
   36.16 -                                NULL, &notOlder);
   36.17 +                                &notOlder,
   36.18 +                                true,   // walk code active on stacks
   36.19 +                                NULL);
   36.20  
   36.21    // Now mark from the roots
   36.22    assert(_revisitStack.isEmpty(), "Should be empty");
   36.23 @@ -2901,13 +2904,16 @@
   36.24  
   36.25    // Mark from roots one level into CMS
   36.26    MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
   36.27 -                                     markBitMap(), true /* nmethods */);
   36.28 +                                     markBitMap());
   36.29    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
   36.30    gch->gen_process_strong_roots(_cmsGen->level(),
   36.31                                  true,   // younger gens are roots
   36.32 +                                true,   // activate StrongRootsScope
   36.33                                  true,   // collecting perm gen
   36.34                                  SharedHeap::ScanningOption(roots_scanning_options()),
   36.35 -                                NULL, &notOlder);
   36.36 +                                &notOlder,
   36.37 +                                true,   // walk code active on stacks
   36.38 +                                NULL);
   36.39  
   36.40    // Now mark from the roots
   36.41    assert(_revisitStack.isEmpty(), "Should be empty");
   36.42 @@ -3484,8 +3490,10 @@
   36.43    FalseClosure falseClosure;
   36.44    // In the case of a synchronous collection, we will elide the
   36.45    // remark step, so it's important to catch all the nmethod oops
   36.46 -  // in this step; hence the last argument to the constrcutor below.
   36.47 -  MarkRefsIntoClosure notOlder(_span, &_markBitMap, !asynch /* nmethods */);
   36.48 +  // in this step.
   36.49 +  // The final 'true' flag to gen_process_strong_roots will ensure this.
   36.50 +  // If 'async' is true, we can relax the nmethod tracing.
   36.51 +  MarkRefsIntoClosure notOlder(_span, &_markBitMap);
   36.52    GenCollectedHeap* gch = GenCollectedHeap::heap();
   36.53  
   36.54    verify_work_stacks_empty();
   36.55 @@ -3504,9 +3512,12 @@
   36.56      gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
   36.57      gch->gen_process_strong_roots(_cmsGen->level(),
   36.58                                    true,   // younger gens are roots
   36.59 +                                  true,   // activate StrongRootsScope
   36.60                                    true,   // collecting perm gen
   36.61                                    SharedHeap::ScanningOption(roots_scanning_options()),
   36.62 -                                  NULL, &notOlder);
   36.63 +                                  &notOlder,
   36.64 +                                  true,   // walk all of code cache if (so & SO_CodeCache)
   36.65 +                                  NULL);
   36.66    }
   36.67  
   36.68    // Clear mod-union table; it will be dirtied in the prologue of
   36.69 @@ -5040,9 +5051,15 @@
   36.70    _timer.start();
   36.71    gch->gen_process_strong_roots(_collector->_cmsGen->level(),
   36.72                                  false,     // yg was scanned above
   36.73 +                                false,     // this is parallel code
   36.74                                  true,      // collecting perm gen
   36.75                                  SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
   36.76 -                                NULL, &par_mrias_cl);
   36.77 +                                &par_mrias_cl,
   36.78 +                                true,   // walk all of code cache if (so & SO_CodeCache)
   36.79 +                                NULL);
   36.80 +  assert(_collector->should_unload_classes()
   36.81 +         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
   36.82 +         "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   36.83    _timer.stop();
   36.84    if (PrintCMSStatistics != 0) {
   36.85      gclog_or_tty->print_cr(
   36.86 @@ -5423,7 +5440,6 @@
   36.87  
   36.88    // Set up for parallel process_strong_roots work.
   36.89    gch->set_par_threads(n_workers);
   36.90 -  gch->change_strong_roots_parity();
   36.91    // We won't be iterating over the cards in the card table updating
   36.92    // the younger_gen cards, so we shouldn't call the following else
   36.93    // the verification code as well as subsequent younger_refs_iterate
   36.94 @@ -5454,8 +5470,10 @@
   36.95    if (n_workers > 1) {
   36.96      // Make refs discovery MT-safe
   36.97      ReferenceProcessorMTMutator mt(ref_processor(), true);
   36.98 +    GenCollectedHeap::StrongRootsScope srs(gch);
   36.99      workers->run_task(&tsk);
  36.100    } else {
  36.101 +    GenCollectedHeap::StrongRootsScope srs(gch);
  36.102      tsk.work(0);
  36.103    }
  36.104    gch->set_par_threads(0);  // 0 ==> non-parallel.
  36.105 @@ -5539,11 +5557,18 @@
  36.106      verify_work_stacks_empty();
  36.107  
  36.108      gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
  36.109 +    GenCollectedHeap::StrongRootsScope srs(gch);
  36.110      gch->gen_process_strong_roots(_cmsGen->level(),
  36.111                                    true,  // younger gens as roots
  36.112 +                                  false, // use the local StrongRootsScope
  36.113                                    true,  // collecting perm gen
  36.114                                    SharedHeap::ScanningOption(roots_scanning_options()),
  36.115 -                                  NULL, &mrias_cl);
  36.116 +                                  &mrias_cl,
  36.117 +                                  true,   // walk code active on stacks
  36.118 +                                  NULL);
  36.119 +    assert(should_unload_classes()
  36.120 +           || (roots_scanning_options() & SharedHeap::SO_CodeCache),
  36.121 +           "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
  36.122    }
  36.123    verify_work_stacks_empty();
  36.124    // Restore evacuated mark words, if any, used for overflow list links
  36.125 @@ -6418,10 +6443,9 @@
  36.126  // generation then this will lose younger_gen cards!
  36.127  
  36.128  MarkRefsIntoClosure::MarkRefsIntoClosure(
  36.129 -  MemRegion span, CMSBitMap* bitMap, bool should_do_nmethods):
  36.130 +  MemRegion span, CMSBitMap* bitMap):
  36.131      _span(span),
  36.132 -    _bitMap(bitMap),
  36.133 -    _should_do_nmethods(should_do_nmethods)
  36.134 +    _bitMap(bitMap)
  36.135  {
  36.136      assert(_ref_processor == NULL, "deliberately left NULL");
  36.137      assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
  36.138 @@ -6442,12 +6466,11 @@
  36.139  
  36.140  // A variant of the above, used for CMS marking verification.
  36.141  MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
  36.142 -  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm,
  36.143 -  bool should_do_nmethods):
  36.144 +  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
  36.145      _span(span),
  36.146      _verification_bm(verification_bm),
  36.147 -    _cms_bm(cms_bm),
  36.148 -    _should_do_nmethods(should_do_nmethods) {
  36.149 +    _cms_bm(cms_bm)
  36.150 +{
  36.151      assert(_ref_processor == NULL, "deliberately left NULL");
  36.152      assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
  36.153  }
    37.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Oct 02 11:26:25 2009 -0700
    37.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Oct 09 15:18:52 2009 -0700
    37.3 @@ -746,10 +746,11 @@
    37.4    // clear the mark bitmap (no grey objects to start with)
    37.5    _nextMarkBitMap->clearAll();
    37.6    PrintReachableClosure prcl(_nextMarkBitMap);
    37.7 -  g1h->process_strong_roots(
    37.8 +  g1h->process_strong_roots(true,    // activate StrongRootsScope
    37.9                              false,   // fake perm gen collection
   37.10                              SharedHeap::SO_AllClasses,
   37.11                              &prcl, // Regular roots
   37.12 +                            NULL,  // do not visit active blobs
   37.13                              &prcl    // Perm Gen Roots
   37.14                              );
   37.15    // The root iteration above "consumed" dirty cards in the perm gen.
   37.16 @@ -852,9 +853,11 @@
   37.17    g1h->set_marking_started();
   37.18    g1h->rem_set()->prepare_for_younger_refs_iterate(false);
   37.19  
   37.20 -  g1h->process_strong_roots(false,   // fake perm gen collection
   37.21 +  g1h->process_strong_roots(true,    // activate StrongRootsScope
   37.22 +                            false,   // fake perm gen collection
   37.23                              SharedHeap::SO_AllClasses,
   37.24                              &notOlder, // Regular roots
   37.25 +                            NULL,     // do not visit active blobs
   37.26                              &older    // Perm Gen Roots
   37.27                              );
   37.28    checkpointRootsInitialPost();
   37.29 @@ -1915,7 +1918,7 @@
   37.30    g1h->ensure_parsability(false);
   37.31  
   37.32    if (ParallelGCThreads > 0) {
   37.33 -    g1h->change_strong_roots_parity();
   37.34 +    G1CollectedHeap::StrongRootsScope srs(g1h);
   37.35      // this is remark, so we'll use up all available threads
   37.36      int active_workers = ParallelGCThreads;
   37.37      set_phase(active_workers, false);
   37.38 @@ -1932,7 +1935,7 @@
   37.39      SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   37.40      guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" );
   37.41    } else {
   37.42 -    g1h->change_strong_roots_parity();
   37.43 +    G1CollectedHeap::StrongRootsScope srs(g1h);
   37.44      // this is remark, so we'll use up all available threads
   37.45      int active_workers = 1;
   37.46      set_phase(active_workers, false);
    38.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Oct 02 11:26:25 2009 -0700
    38.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Oct 09 15:18:52 2009 -0700
    38.3 @@ -2300,9 +2300,12 @@
    38.4    if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
    38.5      if (!silent) { gclog_or_tty->print("roots "); }
    38.6      VerifyRootsClosure rootsCl(use_prev_marking);
    38.7 -    process_strong_roots(false,
    38.8 +    CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
    38.9 +    process_strong_roots(true,  // activate StrongRootsScope
   38.10 +                         false,
   38.11                           SharedHeap::SO_AllClasses,
   38.12                           &rootsCl,
   38.13 +                         &blobsCl,
   38.14                           &rootsCl);
   38.15      rem_set()->invalidate(perm_gen()->used_region(), false);
   38.16      if (!silent) { gclog_or_tty->print("heapRegions "); }
   38.17 @@ -3987,8 +3990,14 @@
   38.18    BufferingOopsInGenClosure buf_scan_perm(scan_perm);
   38.19    buf_scan_perm.set_generation(perm_gen());
   38.20  
   38.21 -  process_strong_roots(collecting_perm_gen, so,
   38.22 +  // Walk the code cache w/o buffering, because StarTask cannot handle
   38.23 +  // unaligned oop locations.
   38.24 +  CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, /*do_marking=*/ true);
   38.25 +
   38.26 +  process_strong_roots(false, // no scoping; this is parallel code
   38.27 +                       collecting_perm_gen, so,
   38.28                         &buf_scan_non_heap_roots,
   38.29 +                       &eager_scan_code_roots,
   38.30                         &buf_scan_perm);
   38.31    // Finish up any enqueued closure apps.
   38.32    buf_scan_non_heap_roots.done();
   38.33 @@ -4078,7 +4087,8 @@
   38.34  void
   38.35  G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure,
   38.36                                         OopClosure* non_root_closure) {
   38.37 -  SharedHeap::process_weak_roots(root_closure, non_root_closure);
   38.38 +  CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false);
   38.39 +  SharedHeap::process_weak_roots(root_closure, &roots_in_blobs, non_root_closure);
   38.40  }
   38.41  
   38.42  
   38.43 @@ -4112,15 +4122,16 @@
   38.44  
   38.45    init_for_evac_failure(NULL);
   38.46  
   38.47 -  change_strong_roots_parity();  // In preparation for parallel strong roots.
   38.48    rem_set()->prepare_for_younger_refs_iterate(true);
   38.49  
   38.50    assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
   38.51    double start_par = os::elapsedTime();
   38.52    if (ParallelGCThreads > 0) {
   38.53      // The individual threads will set their evac-failure closures.
   38.54 +    StrongRootsScope srs(this);
   38.55      workers()->run_task(&g1_par_task);
   38.56    } else {
   38.57 +    StrongRootsScope srs(this);
   38.58      g1_par_task.work(0);
   38.59    }
   38.60  
    39.1 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Oct 02 11:26:25 2009 -0700
    39.2 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Oct 09 15:18:52 2009 -0700
    39.3 @@ -121,9 +121,11 @@
    39.4  
    39.5    SharedHeap* sh = SharedHeap::heap();
    39.6  
    39.7 -  sh->process_strong_roots(true,  // Collecting permanent generation.
    39.8 +  sh->process_strong_roots(true,  // activeate StrongRootsScope
    39.9 +                           true,  // Collecting permanent generation.
   39.10                             SharedHeap::SO_SystemClasses,
   39.11                             &GenMarkSweep::follow_root_closure,
   39.12 +                           &GenMarkSweep::follow_code_root_closure,
   39.13                             &GenMarkSweep::follow_root_closure);
   39.14  
   39.15    // Process reference objects found during marking
   39.16 @@ -286,9 +288,11 @@
   39.17  
   39.18    SharedHeap* sh = SharedHeap::heap();
   39.19  
   39.20 -  sh->process_strong_roots(true,  // Collecting permanent generation.
   39.21 +  sh->process_strong_roots(true,  // activate StrongRootsScope
   39.22 +                           true,  // Collecting permanent generation.
   39.23                             SharedHeap::SO_AllClasses,
   39.24                             &GenMarkSweep::adjust_root_pointer_closure,
   39.25 +                           NULL,  // do not touch code cache here
   39.26                             &GenMarkSweep::adjust_pointer_closure);
   39.27  
   39.28    g1h->ref_processor()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure);
    40.1 --- a/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Fri Oct 02 11:26:25 2009 -0700
    40.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Fri Oct 09 15:18:52 2009 -0700
    40.3 @@ -373,6 +373,7 @@
    40.4  psScavenge.inline.hpp                   psPromotionManager.hpp
    40.5  psScavenge.inline.hpp                   psScavenge.hpp
    40.6  
    40.7 +pcTasks.cpp                             codeCache.hpp
    40.8  pcTasks.cpp                             collectedHeap.hpp
    40.9  pcTasks.cpp                             fprofiler.hpp
   40.10  pcTasks.cpp                             jniHandles.hpp
   40.11 @@ -392,6 +393,7 @@
   40.12  pcTasks.hpp				psTasks.hpp
   40.13  
   40.14  psTasks.cpp                             cardTableExtension.hpp
   40.15 +psTasks.cpp                             codeCache.hpp
   40.16  psTasks.cpp                             fprofiler.hpp
   40.17  psTasks.cpp                             gcTaskManager.hpp
   40.18  psTasks.cpp                             iterator.hpp
    41.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Oct 02 11:26:25 2009 -0700
    41.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Oct 09 15:18:52 2009 -0700
    41.3 @@ -480,12 +480,14 @@
    41.4  
    41.5    par_scan_state.start_strong_roots();
    41.6    gch->gen_process_strong_roots(_gen->level(),
    41.7 -                                true, // Process younger gens, if any,
    41.8 -                                      // as strong roots.
    41.9 -                                false,// not collecting perm generation.
   41.10 +                                true,  // Process younger gens, if any,
   41.11 +                                       // as strong roots.
   41.12 +                                false, // no scope; this is parallel code
   41.13 +                                false, // not collecting perm generation.
   41.14                                  SharedHeap::SO_AllClasses,
   41.15 -                                &par_scan_state.older_gen_closure(),
   41.16 -                                &par_scan_state.to_space_root_closure());
   41.17 +                                &par_scan_state.to_space_root_closure(),
   41.18 +                                true,   // walk *all* scavengable nmethods
   41.19 +                                &par_scan_state.older_gen_closure());
   41.20    par_scan_state.end_strong_roots();
   41.21  
   41.22    // "evacuate followers".
   41.23 @@ -799,15 +801,16 @@
   41.24    ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
   41.25    int n_workers = workers->total_workers();
   41.26    gch->set_par_threads(n_workers);
   41.27 -  gch->change_strong_roots_parity();
   41.28    gch->rem_set()->prepare_for_younger_refs_iterate(true);
   41.29    // It turns out that even when we're using 1 thread, doing the work in a
   41.30    // separate thread causes wide variance in run times.  We can't help this
   41.31    // in the multi-threaded case, but we special-case n=1 here to get
   41.32    // repeatable measurements of the 1-thread overhead of the parallel code.
   41.33    if (n_workers > 1) {
   41.34 +    GenCollectedHeap::StrongRootsScope srs(gch);
   41.35      workers->run_task(&tsk);
   41.36    } else {
   41.37 +    GenCollectedHeap::StrongRootsScope srs(gch);
   41.38      tsk.work(0);
   41.39    }
   41.40    thread_state_set.reset();
    42.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Fri Oct 02 11:26:25 2009 -0700
    42.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Fri Oct 09 15:18:52 2009 -0700
    42.3 @@ -962,6 +962,14 @@
    42.4    _old_gen->resize(desired_free_space);
    42.5  }
    42.6  
    42.7 +ParallelScavengeHeap::ParStrongRootsScope::ParStrongRootsScope() {
    42.8 +  // nothing particular
    42.9 +}
   42.10 +
   42.11 +ParallelScavengeHeap::ParStrongRootsScope::~ParStrongRootsScope() {
   42.12 +  // nothing particular
   42.13 +}
   42.14 +
   42.15  #ifndef PRODUCT
   42.16  void ParallelScavengeHeap::record_gen_tops_before_GC() {
   42.17    if (ZapUnusedHeapArea) {
    43.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Fri Oct 02 11:26:25 2009 -0700
    43.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Fri Oct 09 15:18:52 2009 -0700
    43.3 @@ -234,6 +234,13 @@
    43.4  
    43.5    // Mangle the unused parts of all spaces in the heap
    43.6    void gen_mangle_unused_area() PRODUCT_RETURN;
    43.7 +
    43.8 +  // Call these in sequential code around the processing of strong roots.
    43.9 +  class ParStrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
   43.10 +  public:
   43.11 +    ParStrongRootsScope();
   43.12 +    ~ParStrongRootsScope();
   43.13 +  };
   43.14  };
   43.15  
   43.16  inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val)
    44.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Fri Oct 02 11:26:25 2009 -0700
    44.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Fri Oct 09 15:18:52 2009 -0700
    44.3 @@ -39,12 +39,13 @@
    44.4    ParCompactionManager* cm =
    44.5      ParCompactionManager::gc_thread_compaction_manager(which);
    44.6    PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
    44.7 +  CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true);
    44.8  
    44.9    if (_java_thread != NULL)
   44.10 -    _java_thread->oops_do(&mark_and_push_closure);
   44.11 +    _java_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
   44.12  
   44.13    if (_vm_thread != NULL)
   44.14 -    _vm_thread->oops_do(&mark_and_push_closure);
   44.15 +    _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
   44.16  
   44.17    // Do the real work
   44.18    cm->drain_marking_stacks(&mark_and_push_closure);
   44.19 @@ -78,7 +79,8 @@
   44.20      case threads:
   44.21      {
   44.22        ResourceMark rm;
   44.23 -      Threads::oops_do(&mark_and_push_closure);
   44.24 +      CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true);
   44.25 +      Threads::oops_do(&mark_and_push_closure, &each_active_code_blob);
   44.26      }
   44.27      break;
   44.28  
   44.29 @@ -106,6 +108,11 @@
   44.30        vmSymbols::oops_do(&mark_and_push_closure);
   44.31        break;
   44.32  
   44.33 +    case code_cache:
   44.34 +      // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
   44.35 +      //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
   44.36 +      break;
   44.37 +
   44.38      default:
   44.39        fatal("Unknown root type");
   44.40    }
    45.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Fri Oct 02 11:26:25 2009 -0700
    45.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Fri Oct 09 15:18:52 2009 -0700
    45.3 @@ -92,7 +92,8 @@
    45.4      jvmti                 = 7,
    45.5      system_dictionary     = 8,
    45.6      vm_symbols            = 9,
    45.7 -    reference_processing  = 10
    45.8 +    reference_processing  = 10,
    45.9 +    code_cache            = 11
   45.10    };
   45.11   private:
   45.12    RootType _root_type;
    46.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Oct 02 11:26:25 2009 -0700
    46.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Oct 09 15:18:52 2009 -0700
    46.3 @@ -511,16 +511,22 @@
    46.4    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
    46.5  
    46.6    // General strong roots.
    46.7 -  Universe::oops_do(mark_and_push_closure());
    46.8 -  ReferenceProcessor::oops_do(mark_and_push_closure());
    46.9 -  JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
   46.10 -  Threads::oops_do(mark_and_push_closure());
   46.11 -  ObjectSynchronizer::oops_do(mark_and_push_closure());
   46.12 -  FlatProfiler::oops_do(mark_and_push_closure());
   46.13 -  Management::oops_do(mark_and_push_closure());
   46.14 -  JvmtiExport::oops_do(mark_and_push_closure());
   46.15 -  SystemDictionary::always_strong_oops_do(mark_and_push_closure());
   46.16 -  vmSymbols::oops_do(mark_and_push_closure());
   46.17 +  {
   46.18 +    ParallelScavengeHeap::ParStrongRootsScope psrs;
   46.19 +    Universe::oops_do(mark_and_push_closure());
   46.20 +    ReferenceProcessor::oops_do(mark_and_push_closure());
   46.21 +    JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
   46.22 +    CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
   46.23 +    Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
   46.24 +    ObjectSynchronizer::oops_do(mark_and_push_closure());
   46.25 +    FlatProfiler::oops_do(mark_and_push_closure());
   46.26 +    Management::oops_do(mark_and_push_closure());
   46.27 +    JvmtiExport::oops_do(mark_and_push_closure());
   46.28 +    SystemDictionary::always_strong_oops_do(mark_and_push_closure());
   46.29 +    vmSymbols::oops_do(mark_and_push_closure());
   46.30 +    // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
   46.31 +    //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
   46.32 +  }
   46.33  
   46.34    // Flush marking stack.
   46.35    follow_stack();
   46.36 @@ -617,7 +623,7 @@
   46.37    Universe::oops_do(adjust_root_pointer_closure());
   46.38    ReferenceProcessor::oops_do(adjust_root_pointer_closure());
   46.39    JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
   46.40 -  Threads::oops_do(adjust_root_pointer_closure());
   46.41 +  Threads::oops_do(adjust_root_pointer_closure(), NULL);
   46.42    ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
   46.43    FlatProfiler::oops_do(adjust_root_pointer_closure());
   46.44    Management::oops_do(adjust_root_pointer_closure());
   46.45 @@ -625,6 +631,7 @@
   46.46    // SO_AllClasses
   46.47    SystemDictionary::oops_do(adjust_root_pointer_closure());
   46.48    vmSymbols::oops_do(adjust_root_pointer_closure());
   46.49 +  //CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure());
   46.50  
   46.51    // Now adjust pointers in remaining weak roots.  (All of which should
   46.52    // have been cleared if they pointed to non-surviving objects.)
    47.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Oct 02 11:26:25 2009 -0700
    47.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Oct 09 15:18:52 2009 -0700
    47.3 @@ -2322,6 +2322,7 @@
    47.4  
    47.5    {
    47.6      TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty);
    47.7 +    ParallelScavengeHeap::ParStrongRootsScope psrs;
    47.8  
    47.9      GCTaskQueue* q = GCTaskQueue::create();
   47.10  
   47.11 @@ -2335,6 +2336,7 @@
   47.12      q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
   47.13      q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
   47.14      q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols));
   47.15 +    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
   47.16  
   47.17      if (parallel_gc_threads > 1) {
   47.18        for (uint j = 0; j < parallel_gc_threads; j++) {
   47.19 @@ -2408,7 +2410,7 @@
   47.20    Universe::oops_do(adjust_root_pointer_closure());
   47.21    ReferenceProcessor::oops_do(adjust_root_pointer_closure());
   47.22    JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
   47.23 -  Threads::oops_do(adjust_root_pointer_closure());
   47.24 +  Threads::oops_do(adjust_root_pointer_closure(), NULL);
   47.25    ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
   47.26    FlatProfiler::oops_do(adjust_root_pointer_closure());
   47.27    Management::oops_do(adjust_root_pointer_closure());
    48.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Fri Oct 02 11:26:25 2009 -0700
    48.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Fri Oct 09 15:18:52 2009 -0700
    48.3 @@ -799,8 +799,7 @@
    48.4      FollowRootClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
    48.5      virtual void do_oop(oop* p);
    48.6      virtual void do_oop(narrowOop* p);
    48.7 -    virtual const bool do_nmethods() const { return true; }
    48.8 -  };
    48.9 + };
   48.10  
   48.11    class FollowStackClosure: public VoidClosure {
   48.12     private:
   48.13 @@ -817,6 +816,8 @@
   48.14      AdjustPointerClosure(bool is_root) : _is_root(is_root) { }
   48.15      virtual void do_oop(oop* p);
   48.16      virtual void do_oop(narrowOop* p);
   48.17 +    // do not walk from thread stacks to the code cache on this phase
   48.18 +    virtual void do_code_blob(CodeBlob* cb) const { }
   48.19    };
   48.20  
   48.21    // Closure for verifying update of pointers.  Does not
   48.22 @@ -1063,7 +1064,6 @@
   48.23      MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
   48.24      virtual void do_oop(oop* p);
   48.25      virtual void do_oop(narrowOop* p);
   48.26 -    virtual const bool do_nmethods() const { return true; }
   48.27    };
   48.28  
   48.29    PSParallelCompact();
    49.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Oct 02 11:26:25 2009 -0700
    49.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Oct 09 15:18:52 2009 -0700
    49.3 @@ -358,6 +358,7 @@
    49.4      PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
    49.5      {
    49.6        // TraceTime("Roots");
    49.7 +      ParallelScavengeHeap::ParStrongRootsScope psrs;
    49.8  
    49.9        GCTaskQueue* q = GCTaskQueue::create();
   49.10  
   49.11 @@ -376,6 +377,7 @@
   49.12        q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
   49.13        q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
   49.14        q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
   49.15 +      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
   49.16  
   49.17        ParallelTaskTerminator terminator(
   49.18          gc_task_manager()->workers(),
    50.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Oct 02 11:26:25 2009 -0700
    50.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Oct 09 15:18:52 2009 -0700
    50.3 @@ -66,7 +66,7 @@
    50.4      case threads:
    50.5      {
    50.6        ResourceMark rm;
    50.7 -      Threads::oops_do(&roots_closure);
    50.8 +      Threads::oops_do(&roots_closure, NULL);
    50.9      }
   50.10      break;
   50.11  
   50.12 @@ -90,6 +90,14 @@
   50.13        JvmtiExport::oops_do(&roots_closure);
   50.14        break;
   50.15  
   50.16 +
   50.17 +    case code_cache:
   50.18 +      {
   50.19 +        CodeBlobToOopClosure each_scavengable_code_blob(&roots_closure, /*do_marking=*/ true);
   50.20 +        CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
   50.21 +      }
   50.22 +      break;
   50.23 +
   50.24      default:
   50.25        fatal("Unknown root type");
   50.26    }
   50.27 @@ -107,12 +115,13 @@
   50.28  
   50.29    PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
   50.30    PSScavengeRootsClosure roots_closure(pm);
   50.31 +  CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
   50.32  
   50.33    if (_java_thread != NULL)
   50.34 -    _java_thread->oops_do(&roots_closure);
   50.35 +    _java_thread->oops_do(&roots_closure, &roots_in_blobs);
   50.36  
   50.37    if (_vm_thread != NULL)
   50.38 -    _vm_thread->oops_do(&roots_closure);
   50.39 +    _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
   50.40  
   50.41    // Do the real work
   50.42    pm->drain_stacks(false);
    51.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	Fri Oct 02 11:26:25 2009 -0700
    51.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	Fri Oct 09 15:18:52 2009 -0700
    51.3 @@ -54,7 +54,8 @@
    51.4      flat_profiler         = 5,
    51.5      system_dictionary     = 6,
    51.6      management            = 7,
    51.7 -    jvmti                 = 8
    51.8 +    jvmti                 = 8,
    51.9 +    code_cache            = 9
   51.10    };
   51.11   private:
   51.12    RootType _root_type;
    52.1 --- a/src/share/vm/gc_implementation/shared/markSweep.cpp	Fri Oct 02 11:26:25 2009 -0700
    52.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp	Fri Oct 09 15:18:52 2009 -0700
    52.3 @@ -93,6 +93,7 @@
    52.4  }
    52.5  
    52.6  MarkSweep::FollowRootClosure  MarkSweep::follow_root_closure;
    52.7 +CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
    52.8  
    52.9  void MarkSweep::FollowRootClosure::do_oop(oop* p)       { follow_root(p); }
   52.10  void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
    53.1 --- a/src/share/vm/gc_implementation/shared/markSweep.hpp	Fri Oct 02 11:26:25 2009 -0700
    53.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp	Fri Oct 09 15:18:52 2009 -0700
    53.3 @@ -58,14 +58,12 @@
    53.4     public:
    53.5      virtual void do_oop(oop* p);
    53.6      virtual void do_oop(narrowOop* p);
    53.7 -    virtual const bool do_nmethods() const { return true; }
    53.8    };
    53.9  
   53.10    class MarkAndPushClosure: public OopClosure {
   53.11     public:
   53.12      virtual void do_oop(oop* p);
   53.13      virtual void do_oop(narrowOop* p);
   53.14 -    virtual const bool do_nmethods() const { return true; }
   53.15      virtual const bool should_remember_mdo() const { return true; }
   53.16      virtual void remember_mdo(DataLayout* p) { MarkSweep::revisit_mdo(p); }
   53.17    };
   53.18 @@ -173,6 +171,7 @@
   53.19   public:
   53.20    // Public closures
   53.21    static FollowRootClosure    follow_root_closure;
   53.22 +  static CodeBlobToOopClosure follow_code_root_closure; // => follow_root_closure
   53.23    static MarkAndPushClosure   mark_and_push_closure;
   53.24    static FollowStackClosure   follow_stack_closure;
   53.25    static AdjustPointerClosure adjust_root_pointer_closure;
    54.1 --- a/src/share/vm/gc_interface/collectedHeap.hpp	Fri Oct 02 11:26:25 2009 -0700
    54.2 +++ b/src/share/vm/gc_interface/collectedHeap.hpp	Fri Oct 09 15:18:52 2009 -0700
    54.3 @@ -263,6 +263,14 @@
    54.4      return p == NULL || is_permanent(p);
    54.5    }
    54.6  
    54.7 +  // An object is scavengable if its location may move during a scavenge.
    54.8 +  // (A scavenge is a GC which is not a full GC.)
    54.9 +  // Currently, this just means it is not perm (and not null).
   54.10 +  // This could change if we rethink what's in perm-gen.
   54.11 +  bool is_scavengable(const void *p) const {
   54.12 +    return !is_in_permanent_or_null(p);
   54.13 +  }
   54.14 +
   54.15    // Returns "TRUE" if "p" is a method oop in the
   54.16    // current heap, with high probability. This predicate
   54.17    // is not stable, in general.
    55.1 --- a/src/share/vm/memory/defNewGeneration.cpp	Fri Oct 02 11:26:25 2009 -0700
    55.2 +++ b/src/share/vm/memory/defNewGeneration.cpp	Fri Oct 09 15:18:52 2009 -0700
    55.3 @@ -555,12 +555,14 @@
    55.4           "save marks have not been newly set.");
    55.5  
    55.6    gch->gen_process_strong_roots(_level,
    55.7 -                                true, // Process younger gens, if any, as
    55.8 -                                      // strong roots.
    55.9 -                                false,// not collecting permanent generation.
   55.10 +                                true,  // Process younger gens, if any,
   55.11 +                                       // as strong roots.
   55.12 +                                true,  // activate StrongRootsScope
   55.13 +                                false, // not collecting perm generation.
   55.14                                  SharedHeap::SO_AllClasses,
   55.15 -                                &fsc_with_gc_barrier,
   55.16 -                                &fsc_with_no_gc_barrier);
   55.17 +                                &fsc_with_no_gc_barrier,
   55.18 +                                true,   // walk *all* scavengable nmethods
   55.19 +                                &fsc_with_gc_barrier);
   55.20  
   55.21    // "evacuate followers".
   55.22    evacuate_followers.do_void();
    56.1 --- a/src/share/vm/memory/genCollectedHeap.cpp	Fri Oct 02 11:26:25 2009 -0700
    56.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp	Fri Oct 09 15:18:52 2009 -0700
    56.3 @@ -677,13 +677,23 @@
    56.4  void GenCollectedHeap::
    56.5  gen_process_strong_roots(int level,
    56.6                           bool younger_gens_as_roots,
    56.7 +                         bool activate_scope,
    56.8                           bool collecting_perm_gen,
    56.9                           SharedHeap::ScanningOption so,
   56.10 -                         OopsInGenClosure* older_gens,
   56.11 -                         OopsInGenClosure* not_older_gens) {
   56.12 +                         OopsInGenClosure* not_older_gens,
   56.13 +                         bool do_code_roots,
   56.14 +                         OopsInGenClosure* older_gens) {
   56.15    // General strong roots.
   56.16 -  SharedHeap::process_strong_roots(collecting_perm_gen, so,
   56.17 -                                   not_older_gens, older_gens);
   56.18 +
   56.19 +  if (!do_code_roots) {
   56.20 +    SharedHeap::process_strong_roots(activate_scope, collecting_perm_gen, so,
   56.21 +                                     not_older_gens, NULL, older_gens);
   56.22 +  } else {
   56.23 +    bool do_code_marking = (activate_scope || nmethod::oops_do_marking_is_active());
   56.24 +    CodeBlobToOopClosure code_roots(not_older_gens, /*do_marking=*/ do_code_marking);
   56.25 +    SharedHeap::process_strong_roots(activate_scope, collecting_perm_gen, so,
   56.26 +                                     not_older_gens, &code_roots, older_gens);
   56.27 +  }
   56.28  
   56.29    if (younger_gens_as_roots) {
   56.30      if (!_gen_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
   56.31 @@ -706,8 +716,9 @@
   56.32  }
   56.33  
   56.34  void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure,
   56.35 +                                              CodeBlobClosure* code_roots,
   56.36                                                OopClosure* non_root_closure) {
   56.37 -  SharedHeap::process_weak_roots(root_closure, non_root_closure);
   56.38 +  SharedHeap::process_weak_roots(root_closure, code_roots, non_root_closure);
   56.39    // "Local" "weak" refs
   56.40    for (int i = 0; i < _n_gens; i++) {
   56.41      _gens[i]->ref_processor()->weak_oops_do(root_closure);
    57.1 --- a/src/share/vm/memory/genCollectedHeap.hpp	Fri Oct 02 11:26:25 2009 -0700
    57.2 +++ b/src/share/vm/memory/genCollectedHeap.hpp	Fri Oct 09 15:18:52 2009 -0700
    57.3 @@ -408,16 +408,22 @@
    57.4    // "SO_SystemClasses" to all the "system" classes and loaders;
    57.5    // "SO_Symbols_and_Strings" applies the closure to all entries in
    57.6    // SymbolsTable and StringTable.
    57.7 -  void gen_process_strong_roots(int level, bool younger_gens_as_roots,
    57.8 +  void gen_process_strong_roots(int level,
    57.9 +                                bool younger_gens_as_roots,
   57.10 +                                // The remaining arguments are in an order
   57.11 +                                // consistent with SharedHeap::process_strong_roots:
   57.12 +                                bool activate_scope,
   57.13                                  bool collecting_perm_gen,
   57.14                                  SharedHeap::ScanningOption so,
   57.15 -                                OopsInGenClosure* older_gens,
   57.16 -                                OopsInGenClosure* not_older_gens);
   57.17 +                                OopsInGenClosure* not_older_gens,
   57.18 +                                bool do_code_roots,
   57.19 +                                OopsInGenClosure* older_gens);
   57.20  
   57.21    // Apply "blk" to all the weak roots of the system.  These include
   57.22    // JNI weak roots, the code cache, system dictionary, symbol table,
   57.23    // string table, and referents of reachable weak refs.
   57.24    void gen_process_weak_roots(OopClosure* root_closure,
   57.25 +                              CodeBlobClosure* code_roots,
   57.26                                OopClosure* non_root_closure);
   57.27  
   57.28    // Set the saved marks of generations, if that makes sense.
    58.1 --- a/src/share/vm/memory/genMarkSweep.cpp	Fri Oct 02 11:26:25 2009 -0700
    58.2 +++ b/src/share/vm/memory/genMarkSweep.cpp	Fri Oct 09 15:18:52 2009 -0700
    58.3 @@ -244,9 +244,12 @@
    58.4  
    58.5    gch->gen_process_strong_roots(level,
    58.6                                  false, // Younger gens are not roots.
    58.7 +                                true,  // activate StrongRootsScope
    58.8                                  true,  // Collecting permanent generation.
    58.9                                  SharedHeap::SO_SystemClasses,
   58.10 -                                &follow_root_closure, &follow_root_closure);
   58.11 +                                &follow_root_closure,
   58.12 +                                true,   // walk code active on stacks
   58.13 +                                &follow_root_closure);
   58.14  
   58.15    // Process reference objects found during marking
   58.16    {
   58.17 @@ -338,14 +341,19 @@
   58.18  
   58.19    gch->gen_process_strong_roots(level,
   58.20                                  false, // Younger gens are not roots.
   58.21 +                                true,  // activate StrongRootsScope
   58.22                                  true,  // Collecting permanent generation.
   58.23                                  SharedHeap::SO_AllClasses,
   58.24                                  &adjust_root_pointer_closure,
   58.25 +                                false, // do not walk code
   58.26                                  &adjust_root_pointer_closure);
   58.27  
   58.28    // Now adjust pointers in remaining weak roots.  (All of which should
   58.29    // have been cleared if they pointed to non-surviving objects.)
   58.30 +  CodeBlobToOopClosure adjust_code_pointer_closure(&adjust_pointer_closure,
   58.31 +                                                   /*do_marking=*/ false);
   58.32    gch->gen_process_weak_roots(&adjust_root_pointer_closure,
   58.33 +                              &adjust_code_pointer_closure,
   58.34                                &adjust_pointer_closure);
   58.35  
   58.36    adjust_marks();
    59.1 --- a/src/share/vm/memory/iterator.cpp	Fri Oct 02 11:26:25 2009 -0700
    59.2 +++ b/src/share/vm/memory/iterator.cpp	Fri Oct 09 15:18:52 2009 -0700
    59.3 @@ -46,3 +46,42 @@
    59.4  }
    59.5  #endif
    59.6  
    59.7 +
    59.8 +MarkingCodeBlobClosure::MarkScope::MarkScope(bool activate)
    59.9 +  : _active(activate)
   59.10 +{
   59.11 +  if (_active)  nmethod::oops_do_marking_prologue();
   59.12 +}
   59.13 +
   59.14 +MarkingCodeBlobClosure::MarkScope::~MarkScope() {
   59.15 +  if (_active)  nmethod::oops_do_marking_epilogue();
   59.16 +}
   59.17 +
   59.18 +void MarkingCodeBlobClosure::do_code_blob(CodeBlob* cb) {
   59.19 +  if (!cb->is_nmethod())  return;
   59.20 +  nmethod* nm = (nmethod*) cb;
   59.21 +  if (!nm->test_set_oops_do_mark()) {
   59.22 +    NOT_PRODUCT(if (TraceScavenge)  nm->print_on(tty, "oops_do, 1st visit\n"));
   59.23 +    do_newly_marked_nmethod(nm);
   59.24 +  } else {
   59.25 +    NOT_PRODUCT(if (TraceScavenge)  nm->print_on(tty, "oops_do, skipped on 2nd visit\n"));
   59.26 +  }
   59.27 +}
   59.28 +
   59.29 +void CodeBlobToOopClosure::do_newly_marked_nmethod(nmethod* nm) {
   59.30 +  nm->oops_do(_cl, /*do_strong_roots_only=*/ true);
   59.31 +}
   59.32 +
   59.33 +void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
   59.34 +  if (!_do_marking) {
   59.35 +    NOT_PRODUCT(if (TraceScavenge && Verbose && cb->is_nmethod())  ((nmethod*)cb)->print_on(tty, "oops_do, unmarked visit\n"));
   59.36 +    // This assert won't work, since there are lots of mini-passes
   59.37 +    // (mostly in debug mode) that co-exist with marking phases.
   59.38 +    //assert(!(cb->is_nmethod() && ((nmethod*)cb)->test_oops_do_mark()), "found marked nmethod during mark-free phase");
   59.39 +    cb->oops_do(_cl);
   59.40 +  } else {
   59.41 +    MarkingCodeBlobClosure::do_code_blob(cb);
   59.42 +  }
   59.43 +}
   59.44 +
   59.45 +
    60.1 --- a/src/share/vm/memory/iterator.hpp	Fri Oct 02 11:26:25 2009 -0700
    60.2 +++ b/src/share/vm/memory/iterator.hpp	Fri Oct 09 15:18:52 2009 -0700
    60.3 @@ -24,6 +24,8 @@
    60.4  
    60.5  // The following classes are C++ `closures` for iterating over objects, roots and spaces
    60.6  
    60.7 +class CodeBlob;
    60.8 +class nmethod;
    60.9  class ReferenceProcessor;
   60.10  class DataLayout;
   60.11  
   60.12 @@ -69,9 +71,6 @@
   60.13    virtual const bool should_remember_mdo() const { return false; }
   60.14    virtual void remember_mdo(DataLayout* v) { /* do nothing */ }
   60.15  
   60.16 -  // If "true", invoke on nmethods (when scanning compiled frames).
   60.17 -  virtual const bool do_nmethods() const { return false; }
   60.18 -
   60.19    // The methods below control how object iterations invoking this closure
   60.20    // should be performed:
   60.21  
   60.22 @@ -176,6 +175,51 @@
   60.23  };
   60.24  
   60.25  
   60.26 +// CodeBlobClosure is used for iterating through code blobs
   60.27 +// in the code cache or on thread stacks
   60.28 +
   60.29 +class CodeBlobClosure : public Closure {
   60.30 + public:
   60.31 +  // Called for each code blob.
   60.32 +  virtual void do_code_blob(CodeBlob* cb) = 0;
   60.33 +};
   60.34 +
   60.35 +
   60.36 +class MarkingCodeBlobClosure : public CodeBlobClosure {
   60.37 + public:
   60.38 +  // Called for each code blob, but at most once per unique blob.
   60.39 +  virtual void do_newly_marked_nmethod(nmethod* nm) = 0;
   60.40 +
   60.41 +  virtual void do_code_blob(CodeBlob* cb);
   60.42 +    // = { if (!nmethod(cb)->test_set_oops_do_mark())  do_newly_marked_nmethod(cb); }
   60.43 +
   60.44 +  class MarkScope : public StackObj {
   60.45 +  protected:
   60.46 +    bool _active;
   60.47 +  public:
   60.48 +    MarkScope(bool activate = true);
   60.49 +      // = { if (active) nmethod::oops_do_marking_prologue(); }
   60.50 +    ~MarkScope();
   60.51 +      // = { if (active) nmethod::oops_do_marking_epilogue(); }
   60.52 +  };
   60.53 +};
   60.54 +
   60.55 +
   60.56 +// Applies an oop closure to all ref fields in code blobs
   60.57 +// iterated over in an object iteration.
   60.58 +class CodeBlobToOopClosure: public MarkingCodeBlobClosure {
   60.59 +  OopClosure* _cl;
   60.60 +  bool _do_marking;
   60.61 +public:
   60.62 +  virtual void do_newly_marked_nmethod(nmethod* cb);
   60.63 +    // = { cb->oops_do(_cl); }
   60.64 +  virtual void do_code_blob(CodeBlob* cb);
   60.65 +    // = { if (_do_marking)  super::do_code_blob(cb); else cb->oops_do(_cl); }
   60.66 +  CodeBlobToOopClosure(OopClosure* cl, bool do_marking)
   60.67 +    : _cl(cl), _do_marking(do_marking) {}
   60.68 +};
   60.69 +
   60.70 +
   60.71  
   60.72  // MonitorClosure is used for iterating over monitors in the monitors cache
   60.73  
    61.1 --- a/src/share/vm/memory/sharedHeap.cpp	Fri Oct 02 11:26:25 2009 -0700
    61.2 +++ b/src/share/vm/memory/sharedHeap.cpp	Fri Oct 09 15:18:52 2009 -0700
    61.3 @@ -100,12 +100,27 @@
    61.4           "Not in range.");
    61.5  }
    61.6  
    61.7 -void SharedHeap::process_strong_roots(bool collecting_perm_gen,
    61.8 +SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* outer, bool activate)
    61.9 +  : MarkScope(activate)
   61.10 +{
   61.11 +  if (_active) {
   61.12 +    outer->change_strong_roots_parity();
   61.13 +  }
   61.14 +}
   61.15 +
   61.16 +SharedHeap::StrongRootsScope::~StrongRootsScope() {
   61.17 +  // nothing particular
   61.18 +}
   61.19 +
   61.20 +void SharedHeap::process_strong_roots(bool activate_scope,
   61.21 +                                      bool collecting_perm_gen,
   61.22                                        ScanningOption so,
   61.23                                        OopClosure* roots,
   61.24 +                                      CodeBlobClosure* code_roots,
   61.25                                        OopsInGenClosure* perm_blk) {
   61.26 +  StrongRootsScope srs(this, activate_scope);
   61.27    // General strong roots.
   61.28 -  if (n_par_threads() == 0) change_strong_roots_parity();
   61.29 +  assert(_strong_roots_parity != 0, "must have called prologue code");
   61.30    if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
   61.31      Universe::oops_do(roots);
   61.32      ReferenceProcessor::oops_do(roots);
   61.33 @@ -117,9 +132,9 @@
   61.34      JNIHandles::oops_do(roots);
   61.35    // All threads execute this; the individual threads are task groups.
   61.36    if (ParallelGCThreads > 0) {
   61.37 -    Threads::possibly_parallel_oops_do(roots);
   61.38 +    Threads::possibly_parallel_oops_do(roots, code_roots);
   61.39    } else {
   61.40 -    Threads::oops_do(roots);
   61.41 +    Threads::oops_do(roots, code_roots);
   61.42    }
   61.43    if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
   61.44      ObjectSynchronizer::oops_do(roots);
   61.45 @@ -156,11 +171,29 @@
   61.46    }
   61.47  
   61.48    if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
   61.49 -     if (so & SO_CodeCache) {
   61.50 -       CodeCache::oops_do(roots);
   61.51 -     }
   61.52 +    if (so & SO_CodeCache) {
   61.53 +      // (Currently, CMSCollector uses this to do intermediate-strength collections.)
   61.54 +      assert(collecting_perm_gen, "scanning all of code cache");
   61.55 +      assert(code_roots != NULL, "must supply closure for code cache");
   61.56 +      if (code_roots != NULL) {
   61.57 +        CodeCache::blobs_do(code_roots);
   61.58 +      }
   61.59 +    } else if (so & (SO_SystemClasses|SO_AllClasses)) {
   61.60 +      if (!collecting_perm_gen) {
   61.61 +        // If we are collecting from class statics, but we are not going to
   61.62 +        // visit all of the CodeCache, collect from the non-perm roots if any.
   61.63 +        // This makes the code cache function temporarily as a source of strong
   61.64 +        // roots for oops, until the next major collection.
   61.65 +        //
   61.66 +        // If collecting_perm_gen is true, we require that this phase will call
   61.67 +        // CodeCache::do_unloading.  This will kill off nmethods with expired
   61.68 +        // weak references, such as stale invokedynamic targets.
   61.69 +        CodeCache::scavenge_root_nmethods_do(code_roots);
   61.70 +      }
   61.71 +    }
   61.72      // Verify if the code cache contents are in the perm gen
   61.73 -    NOT_PRODUCT(CodeCache::oops_do(&assert_is_perm_closure));
   61.74 +    NOT_PRODUCT(CodeBlobToOopClosure assert_code_is_perm(&assert_is_perm_closure, /*do_marking=*/ false));
   61.75 +    NOT_PRODUCT(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_perm));
   61.76    }
   61.77  
   61.78    // Roots that should point only into permanent generation.
   61.79 @@ -220,11 +253,12 @@
   61.80  // just skip adjusting any shared entries in the string table.
   61.81  
   61.82  void SharedHeap::process_weak_roots(OopClosure* root_closure,
   61.83 +                                    CodeBlobClosure* code_roots,
   61.84                                      OopClosure* non_root_closure) {
   61.85    // Global (weak) JNI handles
   61.86    JNIHandles::weak_oops_do(&always_true, root_closure);
   61.87  
   61.88 -  CodeCache::oops_do(non_root_closure);
   61.89 +  CodeCache::blobs_do(code_roots);
   61.90    SymbolTable::oops_do(root_closure);
   61.91    if (UseSharedSpaces && !DumpSharedSpaces) {
   61.92      SkipAdjustingSharedStrings skip_closure(root_closure);
    62.1 --- a/src/share/vm/memory/sharedHeap.hpp	Fri Oct 02 11:26:25 2009 -0700
    62.2 +++ b/src/share/vm/memory/sharedHeap.hpp	Fri Oct 09 15:18:52 2009 -0700
    62.3 @@ -165,9 +165,21 @@
    62.4    //   c) to never return a distinguished value (zero) with which such
    62.5    //      task-claiming variables may be initialized, to indicate "never
    62.6    //      claimed".
    62.7 + private:
    62.8    void change_strong_roots_parity();
    62.9 + public:
   62.10    int strong_roots_parity() { return _strong_roots_parity; }
   62.11  
   62.12 +  // Call these in sequential code around process_strong_roots.
   62.13 +  // strong_roots_prologue calls change_strong_roots_parity, if
   62.14 +  // parallel tasks are enabled.
   62.15 +  class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
   62.16 +  public:
   62.17 +    StrongRootsScope(SharedHeap* outer, bool activate = true);
   62.18 +    ~StrongRootsScope();
   62.19 +  };
   62.20 +  friend class StrongRootsScope;
   62.21 +
   62.22    enum ScanningOption {
   62.23      SO_None                = 0x0,
   62.24      SO_AllClasses          = 0x1,
   62.25 @@ -198,15 +210,18 @@
   62.26    // "SO_Symbols" applies the closure to all entries in SymbolsTable;
   62.27    // "SO_Strings" applies the closure to all entries in StringTable;
   62.28    // "SO_CodeCache" applies the closure to all elements of the CodeCache.
   62.29 -  void process_strong_roots(bool collecting_perm_gen,
   62.30 +  void process_strong_roots(bool activate_scope,
   62.31 +                            bool collecting_perm_gen,
   62.32                              ScanningOption so,
   62.33                              OopClosure* roots,
   62.34 +                            CodeBlobClosure* code_roots,
   62.35                              OopsInGenClosure* perm_blk);
   62.36  
   62.37    // Apply "blk" to all the weak roots of the system.  These include
   62.38    // JNI weak roots, the code cache, system dictionary, symbol table,
   62.39    // string table.
   62.40    void process_weak_roots(OopClosure* root_closure,
   62.41 +                          CodeBlobClosure* code_roots,
   62.42                            OopClosure* non_root_closure);
   62.43  
   62.44  
    63.1 --- a/src/share/vm/oops/instanceKlass.cpp	Fri Oct 02 11:26:25 2009 -0700
    63.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Fri Oct 09 15:18:52 2009 -0700
    63.3 @@ -2152,7 +2152,7 @@
    63.4    // This is a short non-blocking critical region, so the no safepoint check is ok.
    63.5    OsrList_lock->lock_without_safepoint_check();
    63.6    assert(n->is_osr_method(), "wrong kind of nmethod");
    63.7 -  n->set_link(osr_nmethods_head());
    63.8 +  n->set_osr_link(osr_nmethods_head());
    63.9    set_osr_nmethods_head(n);
   63.10    // Remember to unlock again
   63.11    OsrList_lock->unlock();
   63.12 @@ -2168,17 +2168,17 @@
   63.13    // Search for match
   63.14    while(cur != NULL && cur != n) {
   63.15      last = cur;
   63.16 -    cur = cur->link();
   63.17 +    cur = cur->osr_link();
   63.18    }
   63.19    if (cur == n) {
   63.20      if (last == NULL) {
   63.21        // Remove first element
   63.22 -      set_osr_nmethods_head(osr_nmethods_head()->link());
   63.23 +      set_osr_nmethods_head(osr_nmethods_head()->osr_link());
   63.24      } else {
   63.25 -      last->set_link(cur->link());
   63.26 +      last->set_osr_link(cur->osr_link());
   63.27      }
   63.28    }
   63.29 -  n->set_link(NULL);
   63.30 +  n->set_osr_link(NULL);
   63.31    // Remember to unlock again
   63.32    OsrList_lock->unlock();
   63.33  }
   63.34 @@ -2195,7 +2195,7 @@
   63.35        OsrList_lock->unlock();
   63.36        return osr;
   63.37      }
   63.38 -    osr = osr->link();
   63.39 +    osr = osr->osr_link();
   63.40    }
   63.41    OsrList_lock->unlock();
   63.42    return NULL;
    64.1 --- a/src/share/vm/oops/oop.hpp	Fri Oct 02 11:26:25 2009 -0700
    64.2 +++ b/src/share/vm/oops/oop.hpp	Fri Oct 09 15:18:52 2009 -0700
    64.3 @@ -330,6 +330,7 @@
    64.4  
    64.5    bool is_perm() const;
    64.6    bool is_perm_or_null() const;
    64.7 +  bool is_scavengable() const;
    64.8    bool is_shared() const;
    64.9    bool is_shared_readonly() const;
   64.10    bool is_shared_readwrite() const;
    65.1 --- a/src/share/vm/oops/oop.inline2.hpp	Fri Oct 02 11:26:25 2009 -0700
    65.2 +++ b/src/share/vm/oops/oop.inline2.hpp	Fri Oct 09 15:18:52 2009 -0700
    65.3 @@ -34,3 +34,7 @@
    65.4  inline bool oopDesc::is_perm_or_null() const {
    65.5    return this == NULL || is_perm();
    65.6  }
    65.7 +
    65.8 +inline bool oopDesc::is_scavengable() const {
    65.9 +  return Universe::heap()->is_scavengable(this);
   65.10 +}
    66.1 --- a/src/share/vm/opto/connode.cpp	Fri Oct 02 11:26:25 2009 -0700
    66.2 +++ b/src/share/vm/opto/connode.cpp	Fri Oct 09 15:18:52 2009 -0700
    66.3 @@ -1085,6 +1085,9 @@
    66.4    switch (op) {
    66.5    case Op_SubX:
    66.6      x = in(1)->in(1);
    66.7 +    // Avoid ideal transformations ping-pong between this and AddP for raw pointers.
    66.8 +    if (phase->find_intptr_t_con(x, -1) == 0)
    66.9 +      break;
   66.10      y = in(1)->in(2);
   66.11      if (fits_in_int(phase->type(y), true)) {
   66.12        return addP_of_X2P(phase, x, y, true);
    67.1 --- a/src/share/vm/opto/escape.cpp	Fri Oct 02 11:26:25 2009 -0700
    67.2 +++ b/src/share/vm/opto/escape.cpp	Fri Oct 09 15:18:52 2009 -0700
    67.3 @@ -524,12 +524,15 @@
    67.4    // inlining) which was not eliminated during parsing since the exactness
    67.5    // of the allocation type was not propagated to the subclass type check.
    67.6    //
    67.7 +  // Or the type 't' could be not related to 'base_t' at all.
    67.8 +  // It could happened when CHA type is different from MDO type on a dead path
    67.9 +  // (for example, from instanceof check) which is not collapsed during parsing.
   67.10 +  //
   67.11    // Do nothing for such AddP node and don't process its users since
   67.12    // this code branch will go away.
   67.13    //
   67.14    if (!t->is_known_instance() &&
   67.15 -      !t->klass()->equals(base_t->klass()) &&
   67.16 -      t->klass()->is_subtype_of(base_t->klass())) {
   67.17 +      !base_t->klass()->is_subtype_of(t->klass())) {
   67.18       return false; // bail out
   67.19    }
   67.20  
    68.1 --- a/src/share/vm/opto/graphKit.cpp	Fri Oct 02 11:26:25 2009 -0700
    68.2 +++ b/src/share/vm/opto/graphKit.cpp	Fri Oct 09 15:18:52 2009 -0700
    68.3 @@ -1450,7 +1450,7 @@
    68.4  
    68.5      case BarrierSet::CardTableModRef:
    68.6      case BarrierSet::CardTableExtension:
    68.7 -      write_barrier_post(store, obj, adr, val, use_precise);
    68.8 +      write_barrier_post(store, obj, adr, adr_idx, val, use_precise);
    68.9        break;
   68.10  
   68.11      case BarrierSet::ModRef:
   68.12 @@ -3165,6 +3165,7 @@
   68.13  void GraphKit::write_barrier_post(Node* oop_store,
   68.14                                    Node* obj,
   68.15                                    Node* adr,
   68.16 +                                  uint  adr_idx,
   68.17                                    Node* val,
   68.18                                    bool use_precise) {
   68.19    // No store check needed if we're storing a NULL or an old object
   68.20 @@ -3214,7 +3215,7 @@
   68.21      __ store(__ ctrl(), card_adr, zero, bt, adr_type);
   68.22    } else {
   68.23      // Specialized path for CM store barrier
   68.24 -    __ storeCM(__ ctrl(), card_adr, zero, oop_store, bt, adr_type);
   68.25 +    __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type);
   68.26    }
   68.27  
   68.28    // Final sync IdealKit and GraphKit.
   68.29 @@ -3314,6 +3315,7 @@
   68.30  void GraphKit::g1_mark_card(IdealKit& ideal,
   68.31                              Node* card_adr,
   68.32                              Node* oop_store,
   68.33 +                            uint oop_alias_idx,
   68.34                              Node* index,
   68.35                              Node* index_adr,
   68.36                              Node* buffer,
   68.37 @@ -3323,7 +3325,7 @@
   68.38    Node* no_base = __ top();
   68.39    BasicType card_bt = T_BYTE;
   68.40    // Smash zero into card. MUST BE ORDERED WRT TO STORE
   68.41 -  __ storeCM(__ ctrl(), card_adr, zero, oop_store, card_bt, Compile::AliasIdxRaw);
   68.42 +  __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw);
   68.43  
   68.44    //  Now do the queue work
   68.45    __ if_then(index, BoolTest::ne, zero); {
   68.46 @@ -3435,13 +3437,13 @@
   68.47          Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
   68.48  
   68.49          __ if_then(card_val, BoolTest::ne, zero); {
   68.50 -          g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
   68.51 +          g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
   68.52          } __ end_if();
   68.53        } __ end_if();
   68.54      } __ end_if();
   68.55    } else {
   68.56      // Object.clone() instrinsic uses this path.
   68.57 -    g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
   68.58 +    g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
   68.59    }
   68.60  
   68.61    // Final sync IdealKit and GraphKit.
    69.1 --- a/src/share/vm/opto/graphKit.hpp	Fri Oct 02 11:26:25 2009 -0700
    69.2 +++ b/src/share/vm/opto/graphKit.hpp	Fri Oct 09 15:18:52 2009 -0700
    69.3 @@ -603,7 +603,8 @@
    69.4    void sync_kit(IdealKit& ideal);
    69.5  
    69.6    // vanilla/CMS post barrier
    69.7 -  void write_barrier_post(Node *store, Node* obj, Node* adr, Node* val, bool use_precise);
    69.8 +  void write_barrier_post(Node *store, Node* obj,
    69.9 +                          Node* adr,  uint adr_idx, Node* val, bool use_precise);
   69.10  
   69.11    // G1 pre/post barriers
   69.12    void g1_write_barrier_pre(Node* obj,
   69.13 @@ -622,7 +623,8 @@
   69.14                               bool use_precise);
   69.15    // Helper function for g1
   69.16    private:
   69.17 -  void g1_mark_card(IdealKit& ideal, Node* card_adr, Node* store,  Node* index, Node* index_adr,
   69.18 +  void g1_mark_card(IdealKit& ideal, Node* card_adr, Node* store, uint oop_alias_idx,
   69.19 +                    Node* index, Node* index_adr,
   69.20                      Node* buffer, const TypeFunc* tf);
   69.21  
   69.22    public:
    70.1 --- a/src/share/vm/opto/idealKit.cpp	Fri Oct 02 11:26:25 2009 -0700
    70.2 +++ b/src/share/vm/opto/idealKit.cpp	Fri Oct 09 15:18:52 2009 -0700
    70.3 @@ -378,7 +378,7 @@
    70.4  
    70.5  // Card mark store. Must be ordered so that it will come after the store of
    70.6  // the oop.
    70.7 -Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store,
    70.8 +Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store, int oop_adr_idx,
    70.9                          BasicType bt,
   70.10                          int adr_idx) {
   70.11    assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
   70.12 @@ -388,7 +388,7 @@
   70.13  
   70.14    // Add required edge to oop_store, optimizer does not support precedence edges.
   70.15    // Convert required edge to precedence edge before allocation.
   70.16 -  Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store);
   70.17 +  Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx);
   70.18  
   70.19    st = transform(st);
   70.20    set_memory(st, adr_idx);
    71.1 --- a/src/share/vm/opto/idealKit.hpp	Fri Oct 02 11:26:25 2009 -0700
    71.2 +++ b/src/share/vm/opto/idealKit.hpp	Fri Oct 09 15:18:52 2009 -0700
    71.3 @@ -216,6 +216,7 @@
    71.4                  Node* adr,
    71.5                  Node* val,
    71.6                  Node* oop_store,
    71.7 +                int oop_adr_idx,
    71.8                  BasicType bt,
    71.9                  int adr_idx);
   71.10  
    72.1 --- a/src/share/vm/opto/library_call.cpp	Fri Oct 02 11:26:25 2009 -0700
    72.2 +++ b/src/share/vm/opto/library_call.cpp	Fri Oct 09 15:18:52 2009 -0700
    72.3 @@ -133,6 +133,7 @@
    72.4      return generate_method_call(method_id, true, false);
    72.5    }
    72.6  
    72.7 +  Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2);
    72.8    bool inline_string_compareTo();
    72.9    bool inline_string_indexOf();
   72.10    Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
   72.11 @@ -796,6 +797,64 @@
   72.12  }
   72.13  
   72.14  
   72.15 +//------------------------------make_string_method_node------------------------
   72.16 +// Helper method for String intrinsic finctions.
   72.17 +Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) {
   72.18 +  const int value_offset  = java_lang_String::value_offset_in_bytes();
   72.19 +  const int count_offset  = java_lang_String::count_offset_in_bytes();
   72.20 +  const int offset_offset = java_lang_String::offset_offset_in_bytes();
   72.21 +
   72.22 +  Node* no_ctrl = NULL;
   72.23 +
   72.24 +  ciInstanceKlass* klass = env()->String_klass();
   72.25 +  const TypeInstPtr* string_type =
   72.26 +        TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
   72.27 +
   72.28 +  const TypeAryPtr* value_type =
   72.29 +        TypeAryPtr::make(TypePtr::NotNull,
   72.30 +                         TypeAry::make(TypeInt::CHAR,TypeInt::POS),
   72.31 +                         ciTypeArrayKlass::make(T_CHAR), true, 0);
   72.32 +
   72.33 +  // Get start addr of string and substring
   72.34 +  Node* str1_valuea  = basic_plus_adr(str1, str1, value_offset);
   72.35 +  Node* str1_value   = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
   72.36 +  Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset);
   72.37 +  Node* str1_offset  = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
   72.38 +  Node* str1_start   = array_element_address(str1_value, str1_offset, T_CHAR);
   72.39 +
   72.40 +  // Pin loads from String::equals() argument since it could be NULL.
   72.41 +  Node* str2_ctrl = (opcode == Op_StrEquals) ? control() : no_ctrl;
   72.42 +  Node* str2_valuea  = basic_plus_adr(str2, str2, value_offset);
   72.43 +  Node* str2_value   = make_load(str2_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
   72.44 +  Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset);
   72.45 +  Node* str2_offset  = make_load(str2_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
   72.46 +  Node* str2_start   = array_element_address(str2_value, str2_offset, T_CHAR);
   72.47 +
   72.48 +  Node* result = NULL;
   72.49 +  switch (opcode) {
   72.50 +  case Op_StrIndexOf:
   72.51 +    result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
   72.52 +                                       str1_start, cnt1, str2_start, cnt2);
   72.53 +    break;
   72.54 +  case Op_StrComp:
   72.55 +    result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
   72.56 +                                    str1_start, cnt1, str2_start, cnt2);
   72.57 +    break;
   72.58 +  case Op_StrEquals:
   72.59 +    result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
   72.60 +                                      str1_start, str2_start, cnt1);
   72.61 +    break;
   72.62 +  default:
   72.63 +    ShouldNotReachHere();
   72.64 +    return NULL;
   72.65 +  }
   72.66 +
   72.67 +  // All these intrinsics have checks.
   72.68 +  C->set_has_split_ifs(true); // Has chance for split-if optimization
   72.69 +
   72.70 +  return _gvn.transform(result);
   72.71 +}
   72.72 +
   72.73  //------------------------------inline_string_compareTo------------------------
   72.74  bool LibraryCallKit::inline_string_compareTo() {
   72.75  
   72.76 @@ -824,16 +883,16 @@
   72.77    ciInstanceKlass* klass = env()->String_klass();
   72.78    const TypeInstPtr* string_type =
   72.79      TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
   72.80 -
   72.81 -  Node* compare =
   72.82 -    _gvn.transform(new (C, 7) StrCompNode(
   72.83 -                        control(),
   72.84 -                        memory(TypeAryPtr::CHARS),
   72.85 -                        memory(string_type->add_offset(value_offset)),
   72.86 -                        memory(string_type->add_offset(count_offset)),
   72.87 -                        memory(string_type->add_offset(offset_offset)),
   72.88 -                        receiver,
   72.89 -                        argument));
   72.90 +  Node* no_ctrl = NULL;
   72.91 +
   72.92 +  // Get counts for string and argument
   72.93 +  Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
   72.94 +  Node* receiver_cnt  = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
   72.95 +
   72.96 +  Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
   72.97 +  Node* argument_cnt  = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
   72.98 +
   72.99 +  Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt);
  72.100    push(compare);
  72.101    return true;
  72.102  }
  72.103 @@ -865,45 +924,71 @@
  72.104      return true;
  72.105    }
  72.106  
  72.107 +  // paths (plus control) merge
  72.108 +  RegionNode* region = new (C, 5) RegionNode(5);
  72.109 +  Node* phi = new (C, 5) PhiNode(region, TypeInt::BOOL);
  72.110 +
  72.111 +  // does source == target string?
  72.112 +  Node* cmp = _gvn.transform(new (C, 3) CmpPNode(receiver, argument));
  72.113 +  Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
  72.114 +
  72.115 +  Node* if_eq = generate_slow_guard(bol, NULL);
  72.116 +  if (if_eq != NULL) {
  72.117 +    // receiver == argument
  72.118 +    phi->init_req(2, intcon(1));
  72.119 +    region->init_req(2, if_eq);
  72.120 +  }
  72.121 +
  72.122    // get String klass for instanceOf
  72.123    ciInstanceKlass* klass = env()->String_klass();
  72.124  
  72.125 -  // two paths (plus control) merge
  72.126 -  RegionNode* region = new (C, 3) RegionNode(3);
  72.127 -  Node* phi = new (C, 3) PhiNode(region, TypeInt::BOOL);
  72.128 -
  72.129 -  Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
  72.130 -  Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
  72.131 -  Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
  72.132 -
  72.133 -  IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
  72.134 -
  72.135 -  Node* if_true  = _gvn.transform(new (C, 1) IfTrueNode(iff));
  72.136 -  set_control(if_true);
  72.137 +  if (!stopped()) {
  72.138 +    Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
  72.139 +    Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
  72.140 +    Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
  72.141 +
  72.142 +    Node* inst_false = generate_guard(bol, NULL, PROB_MIN);
  72.143 +    //instanceOf == true, fallthrough
  72.144 +
  72.145 +    if (inst_false != NULL) {
  72.146 +      phi->init_req(3, intcon(0));
  72.147 +      region->init_req(3, inst_false);
  72.148 +    }
  72.149 +  }
  72.150  
  72.151    const TypeInstPtr* string_type =
  72.152      TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
  72.153  
  72.154 -  // instanceOf == true
  72.155 -  Node* equals =
  72.156 -    _gvn.transform(new (C, 7) StrEqualsNode(
  72.157 -                        control(),
  72.158 -                        memory(TypeAryPtr::CHARS),
  72.159 -                        memory(string_type->add_offset(value_offset)),
  72.160 -                        memory(string_type->add_offset(count_offset)),
  72.161 -                        memory(string_type->add_offset(offset_offset)),
  72.162 -                        receiver,
  72.163 -                        argument));
  72.164 -
  72.165 -  phi->init_req(1, _gvn.transform(equals));
  72.166 -  region->init_req(1, if_true);
  72.167 -
  72.168 -  //instanceOf == false, fallthrough
  72.169 -  Node* if_false = _gvn.transform(new (C, 1) IfFalseNode(iff));
  72.170 -  set_control(if_false);
  72.171 -
  72.172 -  phi->init_req(2, _gvn.transform(intcon(0)));
  72.173 -  region->init_req(2, if_false);
  72.174 +  Node* no_ctrl = NULL;
  72.175 +  Node* receiver_cnt;
  72.176 +  Node* argument_cnt;
  72.177 +
  72.178 +  if (!stopped()) {
  72.179 +    // Get counts for string and argument
  72.180 +    Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
  72.181 +    receiver_cnt  = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
  72.182 +
  72.183 +    // Pin load from argument string since it could be NULL.
  72.184 +    Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
  72.185 +    argument_cnt  = make_load(control(), argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
  72.186 +
  72.187 +    // Check for receiver count != argument count
  72.188 +    Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) );
  72.189 +    Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) );
  72.190 +    Node* if_ne = generate_slow_guard(bol, NULL);
  72.191 +    if (if_ne != NULL) {
  72.192 +      phi->init_req(4, intcon(0));
  72.193 +      region->init_req(4, if_ne);
  72.194 +    }
  72.195 +  }
  72.196 +
  72.197 +  // Check for count == 0 is done by mach node StrEquals.
  72.198 +
  72.199 +  if (!stopped()) {
  72.200 +    Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt);
  72.201 +    phi->init_req(1, equals);
  72.202 +    region->init_req(1, control());
  72.203 +  }
  72.204  
  72.205    // post merge
  72.206    set_control(_gvn.transform(region));
  72.207 @@ -924,10 +1009,8 @@
  72.208    Node *argument1 = pop();
  72.209  
  72.210    Node* equals =
  72.211 -    _gvn.transform(new (C, 3) AryEqNode(control(),
  72.212 -                                        argument1,
  72.213 -                                        argument2)
  72.214 -                   );
  72.215 +    _gvn.transform(new (C, 4) AryEqNode(control(), memory(TypeAryPtr::CHARS),
  72.216 +                                        argument1, argument2) );
  72.217    push(equals);
  72.218    return true;
  72.219  }
  72.220 @@ -1108,19 +1191,40 @@
  72.221        return true;
  72.222      }
  72.223  
  72.224 +    // Make the merge point
  72.225 +    RegionNode* result_rgn = new (C, 3) RegionNode(3);
  72.226 +    Node*       result_phi = new (C, 3) PhiNode(result_rgn, TypeInt::INT);
  72.227 +    Node* no_ctrl  = NULL;
  72.228 +
  72.229      ciInstanceKlass* klass = env()->String_klass();
  72.230      const TypeInstPtr* string_type =
  72.231        TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
  72.232  
  72.233 -    result =
  72.234 -      _gvn.transform(new (C, 7)
  72.235 -                     StrIndexOfNode(control(),
  72.236 -                                    memory(TypeAryPtr::CHARS),
  72.237 -                                    memory(string_type->add_offset(value_offset)),
  72.238 -                                    memory(string_type->add_offset(count_offset)),
  72.239 -                                    memory(string_type->add_offset(offset_offset)),
  72.240 -                                    receiver,
  72.241 -                                    argument));
  72.242 +    // Get counts for string and substr
  72.243 +    Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset);
  72.244 +    Node* source_cnt  = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
  72.245 +
  72.246 +    Node* substr_cnta = basic_plus_adr(argument, argument, count_offset);
  72.247 +    Node* substr_cnt  = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
  72.248 +
  72.249 +    // Check for substr count > string count
  72.250 +    Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) );
  72.251 +    Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) );
  72.252 +    Node* if_gt = generate_slow_guard(bol, NULL);
  72.253 +    if (if_gt != NULL) {
  72.254 +      result_phi->init_req(2, intcon(-1));
  72.255 +      result_rgn->init_req(2, if_gt);
  72.256 +    }
  72.257 +
  72.258 +    if (!stopped()) {
  72.259 +      result = make_string_method_node(Op_StrIndexOf, receiver, source_cnt, argument, substr_cnt);
  72.260 +      result_phi->init_req(1, result);
  72.261 +      result_rgn->init_req(1, control());
  72.262 +    }
  72.263 +    set_control(_gvn.transform(result_rgn));
  72.264 +    record_for_igvn(result_rgn);
  72.265 +    result = _gvn.transform(result_phi);
  72.266 +
  72.267    } else { //Use LibraryCallKit::string_indexOf
  72.268      // don't intrinsify is argument isn't a constant string.
  72.269      if (!argument->is_Con()) {
    73.1 --- a/src/share/vm/opto/matcher.cpp	Fri Oct 02 11:26:25 2009 -0700
    73.2 +++ b/src/share/vm/opto/matcher.cpp	Fri Oct 09 15:18:52 2009 -0700
    73.3 @@ -2032,6 +2032,23 @@
    73.4          n->del_req(3);
    73.5          break;
    73.6        }
    73.7 +      case Op_StrEquals: {
    73.8 +        Node *pair1 = new (C, 3) BinaryNode(n->in(2),n->in(3));
    73.9 +        n->set_req(2,pair1);
   73.10 +        n->set_req(3,n->in(4));
   73.11 +        n->del_req(4);
   73.12 +        break;
   73.13 +      }
   73.14 +      case Op_StrComp:
   73.15 +      case Op_StrIndexOf: {
   73.16 +        Node *pair1 = new (C, 3) BinaryNode(n->in(2),n->in(3));
   73.17 +        n->set_req(2,pair1);
   73.18 +        Node *pair2 = new (C, 3) BinaryNode(n->in(4),n->in(5));
   73.19 +        n->set_req(3,pair2);
   73.20 +        n->del_req(5);
   73.21 +        n->del_req(4);
   73.22 +        break;
   73.23 +      }
   73.24        default:
   73.25          break;
   73.26        }
    74.1 --- a/src/share/vm/opto/memnode.cpp	Fri Oct 02 11:26:25 2009 -0700
    74.2 +++ b/src/share/vm/opto/memnode.cpp	Fri Oct 09 15:18:52 2009 -0700
    74.3 @@ -2313,6 +2313,22 @@
    74.4    return this;
    74.5  }
    74.6  
    74.7 +//=============================================================================
    74.8 +//------------------------------Ideal---------------------------------------
    74.9 +Node *StoreCMNode::Ideal(PhaseGVN *phase, bool can_reshape){
   74.10 +  Node* progress = StoreNode::Ideal(phase, can_reshape);
   74.11 +  if (progress != NULL) return progress;
   74.12 +
   74.13 +  Node* my_store = in(MemNode::OopStore);
   74.14 +  if (my_store->is_MergeMem()) {
   74.15 +    Node* mem = my_store->as_MergeMem()->memory_at(oop_alias_idx());
   74.16 +    set_req(MemNode::OopStore, mem);
   74.17 +    return this;
   74.18 +  }
   74.19 +
   74.20 +  return NULL;
   74.21 +}
   74.22 +
   74.23  //------------------------------Value-----------------------------------------
   74.24  const Type *StoreCMNode::Value( PhaseTransform *phase ) const {
   74.25    // Either input is TOP ==> the result is TOP
   74.26 @@ -2498,7 +2514,7 @@
   74.27  //=============================================================================
   74.28  // Do we match on this edge? No memory edges
   74.29  uint StrCompNode::match_edge(uint idx) const {
   74.30 -  return idx == 5 || idx == 6;
   74.31 +  return idx == 2 || idx == 3; // StrComp (Binary str1 cnt1) (Binary str2 cnt2)
   74.32  }
   74.33  
   74.34  //------------------------------Ideal------------------------------------------
   74.35 @@ -2508,9 +2524,10 @@
   74.36    return remove_dead_region(phase, can_reshape) ? this : NULL;
   74.37  }
   74.38  
   74.39 +//=============================================================================
   74.40  // Do we match on this edge? No memory edges
   74.41  uint StrEqualsNode::match_edge(uint idx) const {
   74.42 -  return idx == 5 || idx == 6;
   74.43 +  return idx == 2 || idx == 3; // StrEquals (Binary str1 str2) cnt
   74.44  }
   74.45  
   74.46  //------------------------------Ideal------------------------------------------
   74.47 @@ -2523,7 +2540,7 @@
   74.48  //=============================================================================
   74.49  // Do we match on this edge? No memory edges
   74.50  uint StrIndexOfNode::match_edge(uint idx) const {
   74.51 -  return idx == 5 || idx == 6;
   74.52 +  return idx == 2 || idx == 3; // StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)
   74.53  }
   74.54  
   74.55  //------------------------------Ideal------------------------------------------
   74.56 @@ -2533,6 +2550,11 @@
   74.57    return remove_dead_region(phase, can_reshape) ? this : NULL;
   74.58  }
   74.59  
   74.60 +//=============================================================================
   74.61 +// Do we match on this edge? No memory edges
   74.62 +uint AryEqNode::match_edge(uint idx) const {
   74.63 +  return idx == 2 || idx == 3; // StrEquals ary1 ary2
   74.64 +}
   74.65  //------------------------------Ideal------------------------------------------
   74.66  // Return a node which is more "ideal" than the current node.  Strip out
   74.67  // control copies
    75.1 --- a/src/share/vm/opto/memnode.hpp	Fri Oct 02 11:26:25 2009 -0700
    75.2 +++ b/src/share/vm/opto/memnode.hpp	Fri Oct 09 15:18:52 2009 -0700
    75.3 @@ -582,12 +582,16 @@
    75.4  // The last StoreCM before a SafePoint must be preserved and occur after its "oop" store
    75.5  // Preceeding equivalent StoreCMs may be eliminated.
    75.6  class StoreCMNode : public StoreNode {
    75.7 + private:
    75.8 +  int _oop_alias_idx;   // The alias_idx of OopStore
    75.9  public:
   75.10 -  StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store ) : StoreNode(c,mem,adr,at,val,oop_store) {}
   75.11 +  StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : StoreNode(c,mem,adr,at,val,oop_store), _oop_alias_idx(oop_alias_idx) {}
   75.12    virtual int Opcode() const;
   75.13    virtual Node *Identity( PhaseTransform *phase );
   75.14 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   75.15    virtual const Type *Value( PhaseTransform *phase ) const;
   75.16    virtual BasicType memory_type() const { return T_VOID; } // unspecific
   75.17 +  int oop_alias_idx() const { return _oop_alias_idx; }
   75.18  };
   75.19  
   75.20  //------------------------------LoadPLockedNode---------------------------------
   75.21 @@ -744,22 +748,15 @@
   75.22  //------------------------------StrComp-------------------------------------
   75.23  class StrCompNode: public Node {
   75.24  public:
   75.25 -  StrCompNode(Node *control,
   75.26 -              Node* char_array_mem,
   75.27 -              Node* value_mem,
   75.28 -              Node* count_mem,
   75.29 -              Node* offset_mem,
   75.30 -              Node* s1, Node* s2): Node(control,
   75.31 -                                        char_array_mem,
   75.32 -                                        value_mem,
   75.33 -                                        count_mem,
   75.34 -                                        offset_mem,
   75.35 -                                        s1, s2) {};
   75.36 +  StrCompNode(Node* control, Node* char_array_mem,
   75.37 +              Node* s1, Node* c1,
   75.38 +              Node* s2, Node* c2): Node(control, char_array_mem,
   75.39 +                                        s1, c1,
   75.40 +                                        s2, c2) {};
   75.41    virtual int Opcode() const;
   75.42    virtual bool depends_only_on_test() const { return false; }
   75.43    virtual const Type* bottom_type() const { return TypeInt::INT; }
   75.44 -  // a StrCompNode (conservatively) aliases with everything:
   75.45 -  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
   75.46 +  virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
   75.47    virtual uint match_edge(uint idx) const;
   75.48    virtual uint ideal_reg() const { return Op_RegI; }
   75.49    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   75.50 @@ -768,22 +765,13 @@
   75.51  //------------------------------StrEquals-------------------------------------
   75.52  class StrEqualsNode: public Node {
   75.53  public:
   75.54 -  StrEqualsNode(Node *control,
   75.55 -                Node* char_array_mem,
   75.56 -                Node* value_mem,
   75.57 -                Node* count_mem,
   75.58 -                Node* offset_mem,
   75.59 -                Node* s1, Node* s2): Node(control,
   75.60 -                                          char_array_mem,
   75.61 -                                          value_mem,
   75.62 -                                          count_mem,
   75.63 -                                          offset_mem,
   75.64 -                                          s1, s2) {};
   75.65 +  StrEqualsNode(Node* control, Node* char_array_mem,
   75.66 +                Node* s1, Node* s2, Node* c): Node(control, char_array_mem,
   75.67 +                                                   s1, s2, c) {};
   75.68    virtual int Opcode() const;
   75.69    virtual bool depends_only_on_test() const { return false; }
   75.70    virtual const Type* bottom_type() const { return TypeInt::BOOL; }
   75.71 -  // a StrEqualsNode (conservatively) aliases with everything:
   75.72 -  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
   75.73 +  virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
   75.74    virtual uint match_edge(uint idx) const;
   75.75    virtual uint ideal_reg() const { return Op_RegI; }
   75.76    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   75.77 @@ -792,22 +780,15 @@
   75.78  //------------------------------StrIndexOf-------------------------------------
   75.79  class StrIndexOfNode: public Node {
   75.80  public:
   75.81 -  StrIndexOfNode(Node *control,
   75.82 -                 Node* char_array_mem,
   75.83 -                 Node* value_mem,
   75.84 -                 Node* count_mem,
   75.85 -                 Node* offset_mem,
   75.86 -                 Node* s1, Node* s2): Node(control,
   75.87 -                                           char_array_mem,
   75.88 -                                           value_mem,
   75.89 -                                           count_mem,
   75.90 -                                           offset_mem,
   75.91 -                                           s1, s2) {};
   75.92 +  StrIndexOfNode(Node* control, Node* char_array_mem,
   75.93 +                 Node* s1, Node* c1,
   75.94 +                 Node* s2, Node* c2): Node(control, char_array_mem,
   75.95 +                                           s1, c1,
   75.96 +                                           s2, c2) {};
   75.97    virtual int Opcode() const;
   75.98    virtual bool depends_only_on_test() const { return false; }
   75.99    virtual const Type* bottom_type() const { return TypeInt::INT; }
  75.100 -  // a StrIndexOfNode (conservatively) aliases with everything:
  75.101 -  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
  75.102 +  virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
  75.103    virtual uint match_edge(uint idx) const;
  75.104    virtual uint ideal_reg() const { return Op_RegI; }
  75.105    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  75.106 @@ -816,11 +797,13 @@
  75.107  //------------------------------AryEq---------------------------------------
  75.108  class AryEqNode: public Node {
  75.109  public:
  75.110 -  AryEqNode(Node *control, Node* s1, Node* s2): Node(control, s1, s2) {};
  75.111 +  AryEqNode(Node* control, Node* char_array_mem,
  75.112 +            Node* s1, Node* s2): Node(control, char_array_mem, s1, s2) {};
  75.113    virtual int Opcode() const;
  75.114    virtual bool depends_only_on_test() const { return false; }
  75.115    virtual const Type* bottom_type() const { return TypeInt::BOOL; }
  75.116    virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
  75.117 +  virtual uint match_edge(uint idx) const;
  75.118    virtual uint ideal_reg() const { return Op_RegI; }
  75.119    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  75.120  };
    76.1 --- a/src/share/vm/opto/output.cpp	Fri Oct 02 11:26:25 2009 -0700
    76.2 +++ b/src/share/vm/opto/output.cpp	Fri Oct 09 15:18:52 2009 -0700
    76.3 @@ -611,7 +611,7 @@
    76.4        assert(cik->is_instance_klass() ||
    76.5               cik->is_array_klass(), "Not supported allocation.");
    76.6        sv = new ObjectValue(spobj->_idx,
    76.7 -                           new ConstantOopWriteValue(cik->encoding()));
    76.8 +                           new ConstantOopWriteValue(cik->constant_encoding()));
    76.9        Compile::set_sv_for_object_node(objs, sv);
   76.10  
   76.11        uint first_ind = spobj->first_index();
   76.12 @@ -702,13 +702,13 @@
   76.13    case Type::AryPtr:
   76.14    case Type::InstPtr:
   76.15    case Type::KlassPtr:          // fall through
   76.16 -    array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->encoding()));
   76.17 +    array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->constant_encoding()));
   76.18      break;
   76.19    case Type::NarrowOop:
   76.20      if (t == TypeNarrowOop::NULL_PTR) {
   76.21        array->append(new ConstantOopWriteValue(NULL));
   76.22      } else {
   76.23 -      array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->encoding()));
   76.24 +      array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->constant_encoding()));
   76.25      }
   76.26      break;
   76.27    case Type::Int:
   76.28 @@ -871,7 +871,7 @@
   76.29            assert(cik->is_instance_klass() ||
   76.30                   cik->is_array_klass(), "Not supported allocation.");
   76.31            ObjectValue* sv = new ObjectValue(spobj->_idx,
   76.32 -                                new ConstantOopWriteValue(cik->encoding()));
   76.33 +                                new ConstantOopWriteValue(cik->constant_encoding()));
   76.34            Compile::set_sv_for_object_node(objs, sv);
   76.35  
   76.36            uint first_ind = spobj->first_index();
   76.37 @@ -890,7 +890,7 @@
   76.38          }
   76.39        } else {
   76.40          const TypePtr *tp = obj_node->bottom_type()->make_ptr();
   76.41 -        scval = new ConstantOopWriteValue(tp->is_instptr()->const_oop()->encoding());
   76.42 +        scval = new ConstantOopWriteValue(tp->is_instptr()->const_oop()->constant_encoding());
   76.43        }
   76.44  
   76.45        OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
    77.1 --- a/src/share/vm/opto/parse.hpp	Fri Oct 02 11:26:25 2009 -0700
    77.2 +++ b/src/share/vm/opto/parse.hpp	Fri Oct 09 15:18:52 2009 -0700
    77.3 @@ -469,7 +469,7 @@
    77.4  
    77.5    // loading from a constant field or the constant pool
    77.6    // returns false if push failed (non-perm field constants only, not ldcs)
    77.7 -  bool push_constant(ciConstant con);
    77.8 +  bool push_constant(ciConstant con, bool require_constant = false);
    77.9  
   77.10    // implementation of object creation bytecodes
   77.11    void do_new();
    78.1 --- a/src/share/vm/opto/parse1.cpp	Fri Oct 02 11:26:25 2009 -0700
    78.2 +++ b/src/share/vm/opto/parse1.cpp	Fri Oct 09 15:18:52 2009 -0700
    78.3 @@ -229,7 +229,9 @@
    78.4      }
    78.5    }
    78.6  
    78.7 -  MethodLivenessResult live_locals = method()->liveness_at_bci(osr_bci());
    78.8 +  // Use the raw liveness computation to make sure that unexpected
    78.9 +  // values don't propagate into the OSR frame.
   78.10 +  MethodLivenessResult live_locals = method()->raw_liveness_at_bci(osr_bci());
   78.11    if (!live_locals.is_valid()) {
   78.12      // Degenerate or breakpointed method.
   78.13      C->record_method_not_compilable("OSR in empty or breakpointed method");
    79.1 --- a/src/share/vm/opto/parse2.cpp	Fri Oct 02 11:26:25 2009 -0700
    79.2 +++ b/src/share/vm/opto/parse2.cpp	Fri Oct 09 15:18:52 2009 -0700
    79.3 @@ -1325,7 +1325,8 @@
    79.4            }
    79.5          }
    79.6        }
    79.7 -      push_constant(constant);
    79.8 +      bool pushed = push_constant(constant, true);
    79.9 +      guarantee(pushed, "must be possible to push this constant");
   79.10      }
   79.11  
   79.12      break;
    80.1 --- a/src/share/vm/opto/parse3.cpp	Fri Oct 02 11:26:25 2009 -0700
    80.2 +++ b/src/share/vm/opto/parse3.cpp	Fri Oct 09 15:18:52 2009 -0700
    80.3 @@ -267,7 +267,7 @@
    80.4  }
    80.5  
    80.6  
    80.7 -bool Parse::push_constant(ciConstant constant) {
    80.8 +bool Parse::push_constant(ciConstant constant, bool require_constant) {
    80.9    switch (constant.basic_type()) {
   80.10    case T_BOOLEAN:  push( intcon(constant.as_boolean()) ); break;
   80.11    case T_INT:      push( intcon(constant.as_int())     ); break;
   80.12 @@ -279,13 +279,16 @@
   80.13    case T_LONG:     push_pair( longcon(constant.as_long()) ); break;
   80.14    case T_ARRAY:
   80.15    case T_OBJECT: {
   80.16 -    // the oop is in perm space if the ciObject "has_encoding"
   80.17 +    // cases:
   80.18 +    //   can_be_constant    = (oop not scavengable || ScavengeRootsInCode != 0)
   80.19 +    //   should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2)
   80.20 +    // An oop is not scavengable if it is in the perm gen.
   80.21      ciObject* oop_constant = constant.as_object();
   80.22      if (oop_constant->is_null_object()) {
   80.23        push( zerocon(T_OBJECT) );
   80.24        break;
   80.25 -    } else if (oop_constant->has_encoding()) {
   80.26 -      push( makecon(TypeOopPtr::make_from_constant(oop_constant)) );
   80.27 +    } else if (require_constant || oop_constant->should_be_constant()) {
   80.28 +      push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant)) );
   80.29        break;
   80.30      } else {
   80.31        // we cannot inline the oop, but we can use it later to narrow a type
    81.1 --- a/src/share/vm/opto/superword.cpp	Fri Oct 02 11:26:25 2009 -0700
    81.2 +++ b/src/share/vm/opto/superword.cpp	Fri Oct 09 15:18:52 2009 -0700
    81.3 @@ -457,10 +457,6 @@
    81.4          } else if (out->Opcode() == Op_StoreCM && out->in(MemNode::OopStore) == n) {
    81.5            // StoreCM has an input edge used as a precedence edge.
    81.6            // Maybe an issue when oop stores are vectorized.
    81.7 -        } else if( out->is_MergeMem() && prev &&
    81.8 -                   prev->Opcode() == Op_StoreCM && out == prev->in(MemNode::OopStore)) {
    81.9 -          // Oop store is a MergeMem! This should not happen. Temporarily remove the assertion
   81.10 -          // for this case because it could not be superwordized anyway.
   81.11          } else {
   81.12            assert(out == prev || prev == NULL, "no branches off of store slice");
   81.13          }
   81.14 @@ -477,6 +473,12 @@
   81.15  // Can s1 and s2 be in a pack with s1 immediately preceding s2 and
   81.16  // s1 aligned at "align"
   81.17  bool SuperWord::stmts_can_pack(Node* s1, Node* s2, int align) {
   81.18 +
   81.19 +  // Do not use superword for non-primitives
   81.20 +  if((s1->is_Mem() && !is_java_primitive(s1->as_Mem()->memory_type())) ||
   81.21 +     (s2->is_Mem() && !is_java_primitive(s2->as_Mem()->memory_type())))
   81.22 +    return false;
   81.23 +
   81.24    if (isomorphic(s1, s2)) {
   81.25      if (independent(s1, s2)) {
   81.26        if (!exists_at(s1, 0) && !exists_at(s2, 1)) {
    82.1 --- a/src/share/vm/opto/type.cpp	Fri Oct 02 11:26:25 2009 -0700
    82.2 +++ b/src/share/vm/opto/type.cpp	Fri Oct 09 15:18:52 2009 -0700
    82.3 @@ -296,7 +296,7 @@
    82.4                                             false, 0, oopDesc::mark_offset_in_bytes());
    82.5    TypeInstPtr::KLASS   = TypeInstPtr::make(TypePtr::BotPTR,  current->env()->Object_klass(),
    82.6                                             false, 0, oopDesc::klass_offset_in_bytes());
    82.7 -  TypeOopPtr::BOTTOM  = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot);
    82.8 +  TypeOopPtr::BOTTOM  = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot);
    82.9  
   82.10    TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR );
   82.11    TypeNarrowOop::BOTTOM   = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
   82.12 @@ -492,8 +492,13 @@
   82.13  bool Type::interface_vs_oop(const Type *t) const {
   82.14    bool result = false;
   82.15  
   82.16 -  const TypeInstPtr* this_inst = this->isa_instptr();
   82.17 -  const TypeInstPtr*    t_inst =    t->isa_instptr();
   82.18 +  const TypePtr* this_ptr = this->make_ptr(); // In case it is narrow_oop
   82.19 +  const TypePtr*    t_ptr =    t->make_ptr();
   82.20 +  if( this_ptr == NULL || t_ptr == NULL )
   82.21 +    return result;
   82.22 +
   82.23 +  const TypeInstPtr* this_inst = this_ptr->isa_instptr();
   82.24 +  const TypeInstPtr*    t_inst =    t_ptr->isa_instptr();
   82.25    if( this_inst && this_inst->is_loaded() && t_inst && t_inst->is_loaded() ) {
   82.26      bool this_interface = this_inst->klass()->is_interface();
   82.27      bool    t_interface =    t_inst->klass()->is_interface();
   82.28 @@ -2249,7 +2254,7 @@
   82.29  const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const {
   82.30    assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
   82.31    if( ptr == _ptr ) return this;
   82.32 -  return make(ptr, _offset);
   82.33 +  return make(ptr, _offset, _instance_id);
   82.34  }
   82.35  
   82.36  //-----------------------------cast_to_instance_id----------------------------
   82.37 @@ -2319,8 +2324,10 @@
   82.38        if (ptr == Null)  return TypePtr::make(AnyPtr, ptr, offset);
   82.39        // else fall through:
   82.40      case TopPTR:
   82.41 -    case AnyNull:
   82.42 -      return make(ptr, offset);
   82.43 +    case AnyNull: {
   82.44 +      int instance_id = meet_instance_id(InstanceTop);
   82.45 +      return make(ptr, offset, instance_id);
   82.46 +    }
   82.47      case BotPTR:
   82.48      case NotNull:
   82.49        return TypePtr::make(AnyPtr, ptr, offset);
   82.50 @@ -2411,14 +2418,13 @@
   82.51  
   82.52  //------------------------------make_from_constant-----------------------------
   82.53  // Make a java pointer from an oop constant
   82.54 -const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o) {
   82.55 +const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
   82.56    if (o->is_method_data() || o->is_method()) {
   82.57      // Treat much like a typeArray of bytes, like below, but fake the type...
   82.58 -    assert(o->has_encoding(), "must be a perm space object");
   82.59      const Type* etype = (Type*)get_const_basic_type(T_BYTE);
   82.60      const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
   82.61      ciKlass *klass = ciTypeArrayKlass::make((BasicType) T_BYTE);
   82.62 -    assert(o->has_encoding(), "method data oops should be tenured");
   82.63 +    assert(o->can_be_constant(), "method data oops should be tenured");
   82.64      const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
   82.65      return arr;
   82.66    } else {
   82.67 @@ -2427,8 +2433,9 @@
   82.68      ciKlass *klass = o->klass();
   82.69      if (klass->is_instance_klass()) {
   82.70        // Element is an instance
   82.71 -      if (!o->has_encoding()) {  // not a perm-space constant
   82.72 -        // %%% remove this restriction by rewriting non-perm ConPNodes in a later phase
   82.73 +      if (require_constant) {
   82.74 +        if (!o->can_be_constant())  return NULL;
   82.75 +      } else if (!o->should_be_constant()) {
   82.76          return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0);
   82.77        }
   82.78        return TypeInstPtr::make(o);
   82.79 @@ -2440,8 +2447,9 @@
   82.80        // We used to pass NotNull in here, asserting that the sub-arrays
   82.81        // are all not-null.  This is not true in generally, as code can
   82.82        // slam NULLs down in the subarrays.
   82.83 -      if (!o->has_encoding()) {  // not a perm-space constant
   82.84 -        // %%% remove this restriction by rewriting non-perm ConPNodes in a later phase
   82.85 +      if (require_constant) {
   82.86 +        if (!o->can_be_constant())  return NULL;
   82.87 +      } else if (!o->should_be_constant()) {
   82.88          return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
   82.89        }
   82.90        const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
   82.91 @@ -2453,8 +2461,9 @@
   82.92        const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
   82.93        // We used to pass NotNull in here, asserting that the array pointer
   82.94        // is not-null. That was not true in general.
   82.95 -      if (!o->has_encoding()) {  // not a perm-space constant
   82.96 -        // %%% remove this restriction by rewriting non-perm ConPNodes in a later phase
   82.97 +      if (require_constant) {
   82.98 +        if (!o->can_be_constant())  return NULL;
   82.99 +      } else if (!o->should_be_constant()) {
  82.100          return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
  82.101        }
  82.102        const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
  82.103 @@ -2483,7 +2492,7 @@
  82.104      ShouldNotReachHere();
  82.105    }
  82.106  
  82.107 -  return (intptr_t)const_oop()->encoding();
  82.108 +  return (intptr_t)const_oop()->constant_encoding();
  82.109  }
  82.110  
  82.111  
  82.112 @@ -2591,7 +2600,7 @@
  82.113  
  82.114  //------------------------------add_offset-------------------------------------
  82.115  const TypePtr *TypeOopPtr::add_offset( intptr_t offset ) const {
  82.116 -  return make( _ptr, xadd_offset(offset) );
  82.117 +  return make( _ptr, xadd_offset(offset), _instance_id);
  82.118  }
  82.119  
  82.120  //------------------------------meet_instance_id--------------------------------
  82.121 @@ -2694,6 +2703,7 @@
  82.122  const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst) const {
  82.123      int off = meet_offset(tinst->offset());
  82.124      PTR ptr = meet_ptr(tinst->ptr());
  82.125 +    int instance_id = meet_instance_id(tinst->instance_id());
  82.126  
  82.127      const TypeInstPtr *loaded    = is_loaded() ? this  : tinst;
  82.128      const TypeInstPtr *unloaded  = is_loaded() ? tinst : this;
  82.129 @@ -2714,7 +2724,7 @@
  82.130        assert(loaded->ptr() != TypePtr::Null, "insanity check");
  82.131        //
  82.132        if(      loaded->ptr() == TypePtr::TopPTR ) { return unloaded; }
  82.133 -      else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make( ptr, unloaded->klass() ); }
  82.134 +      else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make( ptr, unloaded->klass(), false, NULL, off, instance_id ); }
  82.135        else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; }
  82.136        else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) {
  82.137          if (unloaded->ptr() == TypePtr::BotPTR  ) { return TypeInstPtr::BOTTOM;  }
  82.138 @@ -3338,14 +3348,19 @@
  82.139        ciObject* o = const_oop();
  82.140        if( _ptr == Constant ) {
  82.141          if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) {
  82.142 +          xk = (klass() == tap->klass());
  82.143            ptr = NotNull;
  82.144            o = NULL;
  82.145            instance_id = InstanceBot;
  82.146 +        } else {
  82.147 +          xk = true;
  82.148          }
  82.149        } else if( above_centerline(_ptr) ) {
  82.150          o = tap->const_oop();
  82.151 +        xk = true;
  82.152 +      } else {
  82.153 +        xk = this->_klass_is_exact;
  82.154        }
  82.155 -      xk = true;
  82.156        return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, instance_id );
  82.157      }
  82.158      case NotNull:
    83.1 --- a/src/share/vm/opto/type.hpp	Fri Oct 02 11:26:25 2009 -0700
    83.2 +++ b/src/share/vm/opto/type.hpp	Fri Oct 09 15:18:52 2009 -0700
    83.3 @@ -711,10 +711,13 @@
    83.4      return make_from_klass_common(klass, false, false);
    83.5    }
    83.6    // Creates a singleton type given an object.
    83.7 -  static const TypeOopPtr* make_from_constant(ciObject* o);
    83.8 +  // If the object cannot be rendered as a constant,
    83.9 +  // may return a non-singleton type.
   83.10 +  // If require_constant, produce a NULL if a singleton is not possible.
   83.11 +  static const TypeOopPtr* make_from_constant(ciObject* o, bool require_constant = false);
   83.12  
   83.13    // Make a generic (unclassed) pointer to an oop.
   83.14 -  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id = InstanceBot);
   83.15 +  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id);
   83.16  
   83.17    ciObject* const_oop()    const { return _const_oop; }
   83.18    virtual ciKlass* klass() const { return _klass;     }
    84.1 --- a/src/share/vm/prims/jvmtiTagMap.cpp	Fri Oct 02 11:26:25 2009 -0700
    84.2 +++ b/src/share/vm/prims/jvmtiTagMap.cpp	Fri Oct 09 15:18:52 2009 -0700
    84.3 @@ -3126,6 +3126,12 @@
    84.4    // exceptions) will be visible.
    84.5    blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
    84.6    Universe::oops_do(&blk);
    84.7 +
    84.8 +  // If there are any non-perm roots in the code cache, visit them.
    84.9 +  blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
   84.10 +  CodeBlobToOopClosure look_in_blobs(&blk, false);
   84.11 +  CodeCache::scavenge_root_nmethods_do(&look_in_blobs);
   84.12 +
   84.13    return true;
   84.14  }
   84.15  
    85.1 --- a/src/share/vm/runtime/arguments.cpp	Fri Oct 02 11:26:25 2009 -0700
    85.2 +++ b/src/share/vm/runtime/arguments.cpp	Fri Oct 09 15:18:52 2009 -0700
    85.3 @@ -2648,16 +2648,22 @@
    85.4  
    85.5    if (EnableInvokeDynamic && !EnableMethodHandles) {
    85.6      if (!FLAG_IS_DEFAULT(EnableMethodHandles)) {
    85.7 -      warning("forcing EnableMethodHandles true to allow EnableInvokeDynamic");
    85.8 +      warning("forcing EnableMethodHandles true because EnableInvokeDynamic is true");
    85.9      }
   85.10      EnableMethodHandles = true;
   85.11    }
   85.12    if (EnableMethodHandles && !AnonymousClasses) {
   85.13      if (!FLAG_IS_DEFAULT(AnonymousClasses)) {
   85.14 -      warning("forcing AnonymousClasses true to enable EnableMethodHandles");
   85.15 +      warning("forcing AnonymousClasses true because EnableMethodHandles is true");
   85.16      }
   85.17      AnonymousClasses = true;
   85.18    }
   85.19 +  if ((EnableMethodHandles || AnonymousClasses) && ScavengeRootsInCode == 0) {
   85.20 +    if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {
   85.21 +      warning("forcing ScavengeRootsInCode non-zero because EnableMethodHandles or AnonymousClasses is true");
   85.22 +    }
   85.23 +    ScavengeRootsInCode = 1;
   85.24 +  }
   85.25  
   85.26    if (PrintGCDetails) {
   85.27      // Turn on -verbose:gc options as well
    86.1 --- a/src/share/vm/runtime/frame.cpp	Fri Oct 02 11:26:25 2009 -0700
    86.2 +++ b/src/share/vm/runtime/frame.cpp	Fri Oct 09 15:18:52 2009 -0700
    86.3 @@ -1043,7 +1043,7 @@
    86.4    finder.oops_do();
    86.5  }
    86.6  
    86.7 -void frame::oops_code_blob_do(OopClosure* f, const RegisterMap* reg_map) {
    86.8 +void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) {
    86.9    assert(_cb != NULL, "sanity check");
   86.10    if (_cb->oop_maps() != NULL) {
   86.11      OopMapSet::oops_do(this, reg_map, f);
   86.12 @@ -1058,21 +1058,9 @@
   86.13    // oops referenced from nmethods active on thread stacks so as to
   86.14    // prevent them from being collected. However, this visit should be
   86.15    // restricted to certain phases of the collection only. The
   86.16 -  // closure answers whether it wants nmethods to be traced.
   86.17 -  // (All CodeBlob subtypes other than NMethod currently have
   86.18 -  // an empty oops_do() method.
   86.19 -  if (f->do_nmethods()) {
   86.20 -    _cb->oops_do(f);
   86.21 -  }
   86.22 -}
   86.23 -
   86.24 -void frame::nmethods_code_blob_do() {
   86.25 -  assert(_cb != NULL, "sanity check");
   86.26 -
   86.27 -  // If we see an activation belonging to a non_entrant nmethod, we mark it.
   86.28 -  if (_cb->is_nmethod() && ((nmethod *)_cb)->is_not_entrant()) {
   86.29 -    ((nmethod*)_cb)->mark_as_seen_on_stack();
   86.30 -  }
   86.31 +  // closure decides how it wants nmethods to be traced.
   86.32 +  if (cf != NULL)
   86.33 +    cf->do_code_blob(_cb);
   86.34  }
   86.35  
   86.36  class CompiledArgumentOopFinder: public SignatureInfo {
   86.37 @@ -1201,18 +1189,18 @@
   86.38  }
   86.39  
   86.40  
   86.41 -void frame::oops_do_internal(OopClosure* f, RegisterMap* map, bool use_interpreter_oop_map_cache) {
   86.42 +void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
   86.43           if (is_interpreted_frame())    { oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
   86.44    } else if (is_entry_frame())          { oops_entry_do      (f, map);
   86.45 -  } else if (CodeCache::contains(pc())) { oops_code_blob_do  (f, map);
   86.46 +  } else if (CodeCache::contains(pc())) { oops_code_blob_do  (f, cf, map);
   86.47    } else {
   86.48      ShouldNotReachHere();
   86.49    }
   86.50  }
   86.51  
   86.52 -void frame::nmethods_do() {
   86.53 +void frame::nmethods_do(CodeBlobClosure* cf) {
   86.54    if (_cb != NULL && _cb->is_nmethod()) {
   86.55 -    nmethods_code_blob_do();
   86.56 +    cf->do_code_blob(_cb);
   86.57    }
   86.58  }
   86.59  
   86.60 @@ -1358,7 +1346,7 @@
   86.61      }
   86.62    }
   86.63    COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");)
   86.64 -  oops_do_internal(&VerifyOopClosure::verify_oop, (RegisterMap*)map, false);
   86.65 +  oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
   86.66  }
   86.67  
   86.68  
    87.1 --- a/src/share/vm/runtime/frame.hpp	Fri Oct 02 11:26:25 2009 -0700
    87.2 +++ b/src/share/vm/runtime/frame.hpp	Fri Oct 09 15:18:52 2009 -0700
    87.3 @@ -384,16 +384,14 @@
    87.4    void oops_interpreted_arguments_do(symbolHandle signature, bool is_static, OopClosure* f);
    87.5  
    87.6    // Iteration of oops
    87.7 -  void oops_do_internal(OopClosure* f, RegisterMap* map, bool use_interpreter_oop_map_cache);
    87.8 +  void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
    87.9    void oops_entry_do(OopClosure* f, const RegisterMap* map);
   87.10 -  void oops_code_blob_do(OopClosure* f, const RegisterMap* map);
   87.11 +  void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map);
   87.12    int adjust_offset(methodOop method, int index); // helper for above fn
   87.13 -  // Iteration of nmethods
   87.14 -  void nmethods_code_blob_do();
   87.15   public:
   87.16    // Memory management
   87.17 -  void oops_do(OopClosure* f, RegisterMap* map) { oops_do_internal(f, map, true); }
   87.18 -  void nmethods_do();
   87.19 +  void oops_do(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cf, map, true); }
   87.20 +  void nmethods_do(CodeBlobClosure* cf);
   87.21  
   87.22    void gc_prologue();
   87.23    void gc_epilogue();
    88.1 --- a/src/share/vm/runtime/globals.hpp	Fri Oct 02 11:26:25 2009 -0700
    88.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Oct 09 15:18:52 2009 -0700
    88.3 @@ -714,6 +714,11 @@
    88.4    diagnostic(bool, TraceNMethodInstalls, false,                             \
    88.5               "Trace nmethod intallation")                                   \
    88.6                                                                              \
    88.7 +  diagnostic(intx, ScavengeRootsInCode, 0,                                  \
    88.8 +             "0: do not allow scavengable oops in the code cache; "         \
    88.9 +             "1: allow scavenging from the code cache; "                    \
   88.10 +             "2: emit as many constants as the compiler can see")           \
   88.11 +                                                                            \
   88.12    diagnostic(bool, TraceOSRBreakpoint, false,                               \
   88.13               "Trace OSR Breakpoint ")                                       \
   88.14                                                                              \
    89.1 --- a/src/share/vm/runtime/sweeper.cpp	Fri Oct 02 11:26:25 2009 -0700
    89.2 +++ b/src/share/vm/runtime/sweeper.cpp	Fri Oct 09 15:18:52 2009 -0700
    89.3 @@ -34,6 +34,17 @@
    89.4  jint      NMethodSweeper::_not_entrant_seen_on_stack = 0;
    89.5  bool      NMethodSweeper::_rescan = false;
    89.6  
    89.7 +class MarkActivationClosure: public CodeBlobClosure {
    89.8 +public:
    89.9 +  virtual void do_code_blob(CodeBlob* cb) {
   89.10 +    // If we see an activation belonging to a non_entrant nmethod, we mark it.
   89.11 +    if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
   89.12 +      ((nmethod*)cb)->mark_as_seen_on_stack();
   89.13 +    }
   89.14 +  }
   89.15 +};
   89.16 +static MarkActivationClosure mark_activation_closure;
   89.17 +
   89.18  void NMethodSweeper::sweep() {
   89.19    assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
   89.20    if (!MethodFlushing) return;
   89.21 @@ -57,7 +68,7 @@
   89.22      if (PrintMethodFlushing) {
   89.23        tty->print_cr("### Sweep: stack traversal %d", _traversals);
   89.24      }
   89.25 -    Threads::nmethods_do();
   89.26 +    Threads::nmethods_do(&mark_activation_closure);
   89.27  
   89.28      // reset the flags since we started a scan from the beginning.
   89.29      _rescan = false;
    90.1 --- a/src/share/vm/runtime/thread.cpp	Fri Oct 02 11:26:25 2009 -0700
    90.2 +++ b/src/share/vm/runtime/thread.cpp	Fri Oct 09 15:18:52 2009 -0700
    90.3 @@ -683,14 +683,15 @@
    90.4    return false;
    90.5  }
    90.6  
    90.7 -void Thread::oops_do(OopClosure* f) {
    90.8 +void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
    90.9    active_handles()->oops_do(f);
   90.10    // Do oop for ThreadShadow
   90.11    f->do_oop((oop*)&_pending_exception);
   90.12    handle_area()->oops_do(f);
   90.13  }
   90.14  
   90.15 -void Thread::nmethods_do() {
   90.16 +void Thread::nmethods_do(CodeBlobClosure* cf) {
   90.17 +  // no nmethods in a generic thread...
   90.18  }
   90.19  
   90.20  void Thread::print_on(outputStream* st) const {
   90.21 @@ -2316,12 +2317,12 @@
   90.22  }
   90.23  
   90.24  
   90.25 -void JavaThread::oops_do(OopClosure* f) {
   90.26 +void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   90.27    // The ThreadProfiler oops_do is done from FlatProfiler::oops_do
   90.28    // since there may be more than one thread using each ThreadProfiler.
   90.29  
   90.30    // Traverse the GCHandles
   90.31 -  Thread::oops_do(f);
   90.32 +  Thread::oops_do(f, cf);
   90.33  
   90.34    assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
   90.35            (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
   90.36 @@ -2347,7 +2348,7 @@
   90.37  
   90.38      // Traverse the execution stack
   90.39      for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
   90.40 -      fst.current()->oops_do(f, fst.register_map());
   90.41 +      fst.current()->oops_do(f, cf, fst.register_map());
   90.42      }
   90.43    }
   90.44  
   90.45 @@ -2379,9 +2380,8 @@
   90.46    }
   90.47  }
   90.48  
   90.49 -void JavaThread::nmethods_do() {
   90.50 -  // Traverse the GCHandles
   90.51 -  Thread::nmethods_do();
   90.52 +void JavaThread::nmethods_do(CodeBlobClosure* cf) {
   90.53 +  Thread::nmethods_do(cf);  // (super method is a no-op)
   90.54  
   90.55    assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
   90.56            (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
   90.57 @@ -2389,7 +2389,7 @@
   90.58    if (has_last_Java_frame()) {
   90.59      // Traverse the execution stack
   90.60      for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
   90.61 -      fst.current()->nmethods_do();
   90.62 +      fst.current()->nmethods_do(cf);
   90.63      }
   90.64    }
   90.65  }
   90.66 @@ -2463,7 +2463,7 @@
   90.67  
   90.68  void JavaThread::verify() {
   90.69    // Verify oops in the thread.
   90.70 -  oops_do(&VerifyOopClosure::verify_oop);
   90.71 +  oops_do(&VerifyOopClosure::verify_oop, NULL);
   90.72  
   90.73    // Verify the stack frames.
   90.74    frames_do(frame_verify);
   90.75 @@ -3602,14 +3602,14 @@
   90.76  // uses the Threads_lock to gurantee this property. It also makes sure that
   90.77  // all threads gets blocked when exiting or starting).
   90.78  
   90.79 -void Threads::oops_do(OopClosure* f) {
   90.80 +void Threads::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   90.81    ALL_JAVA_THREADS(p) {
   90.82 -    p->oops_do(f);
   90.83 +    p->oops_do(f, cf);
   90.84    }
   90.85 -  VMThread::vm_thread()->oops_do(f);
   90.86 +  VMThread::vm_thread()->oops_do(f, cf);
   90.87  }
   90.88  
   90.89 -void Threads::possibly_parallel_oops_do(OopClosure* f) {
   90.90 +void Threads::possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf) {
   90.91    // Introduce a mechanism allowing parallel threads to claim threads as
   90.92    // root groups.  Overhead should be small enough to use all the time,
   90.93    // even in sequential code.
   90.94 @@ -3618,12 +3618,12 @@
   90.95    int cp = SharedHeap::heap()->strong_roots_parity();
   90.96    ALL_JAVA_THREADS(p) {
   90.97      if (p->claim_oops_do(is_par, cp)) {
   90.98 -      p->oops_do(f);
   90.99 +      p->oops_do(f, cf);
  90.100      }
  90.101    }
  90.102    VMThread* vmt = VMThread::vm_thread();
  90.103    if (vmt->claim_oops_do(is_par, cp))
  90.104 -    vmt->oops_do(f);
  90.105 +    vmt->oops_do(f, cf);
  90.106  }
  90.107  
  90.108  #ifndef SERIALGC
  90.109 @@ -3644,11 +3644,11 @@
  90.110  }
  90.111  #endif // SERIALGC
  90.112  
  90.113 -void Threads::nmethods_do() {
  90.114 +void Threads::nmethods_do(CodeBlobClosure* cf) {
  90.115    ALL_JAVA_THREADS(p) {
  90.116 -    p->nmethods_do();
  90.117 +    p->nmethods_do(cf);
  90.118    }
  90.119 -  VMThread::vm_thread()->nmethods_do();
  90.120 +  VMThread::vm_thread()->nmethods_do(cf);
  90.121  }
  90.122  
  90.123  void Threads::gc_epilogue() {
    91.1 --- a/src/share/vm/runtime/thread.hpp	Fri Oct 02 11:26:25 2009 -0700
    91.2 +++ b/src/share/vm/runtime/thread.hpp	Fri Oct 09 15:18:52 2009 -0700
    91.3 @@ -374,7 +374,8 @@
    91.4  
    91.5    // GC support
    91.6    // Apply "f->do_oop" to all root oops in "this".
    91.7 -  void oops_do(OopClosure* f);
    91.8 +  // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
    91.9 +  void oops_do(OopClosure* f, CodeBlobClosure* cf);
   91.10  
   91.11    // Handles the parallel case for the method below.
   91.12  private:
   91.13 @@ -398,7 +399,7 @@
   91.14    }
   91.15  
   91.16    // Sweeper support
   91.17 -  void nmethods_do();
   91.18 +  void nmethods_do(CodeBlobClosure* cf);
   91.19  
   91.20    // Tells if adr belong to this thread. This is used
   91.21    // for checking if a lock is owned by the running thread.
   91.22 @@ -1229,10 +1230,10 @@
   91.23    void frames_do(void f(frame*, const RegisterMap*));
   91.24  
   91.25    // Memory operations
   91.26 -  void oops_do(OopClosure* f);
   91.27 +  void oops_do(OopClosure* f, CodeBlobClosure* cf);
   91.28  
   91.29    // Sweeper operations
   91.30 -  void nmethods_do();
   91.31 +  void nmethods_do(CodeBlobClosure* cf);
   91.32  
   91.33    // Memory management operations
   91.34    void gc_epilogue();
   91.35 @@ -1620,9 +1621,9 @@
   91.36  
   91.37    // Apply "f->do_oop" to all root oops in all threads.
   91.38    // This version may only be called by sequential code.
   91.39 -  static void oops_do(OopClosure* f);
   91.40 +  static void oops_do(OopClosure* f, CodeBlobClosure* cf);
   91.41    // This version may be called by sequential or parallel code.
   91.42 -  static void possibly_parallel_oops_do(OopClosure* f);
   91.43 +  static void possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf);
   91.44    // This creates a list of GCTasks, one per thread.
   91.45    static void create_thread_roots_tasks(GCTaskQueue* q);
   91.46    // This creates a list of GCTasks, one per thread, for marking objects.
   91.47 @@ -1630,13 +1631,13 @@
   91.48  
   91.49    // Apply "f->do_oop" to roots in all threads that
   91.50    // are part of compiled frames
   91.51 -  static void compiled_frame_oops_do(OopClosure* f);
   91.52 +  static void compiled_frame_oops_do(OopClosure* f, CodeBlobClosure* cf);
   91.53  
   91.54    static void convert_hcode_pointers();
   91.55    static void restore_hcode_pointers();
   91.56  
   91.57    // Sweeper
   91.58 -  static void nmethods_do();
   91.59 +  static void nmethods_do(CodeBlobClosure* cf);
   91.60  
   91.61    static void gc_epilogue();
   91.62    static void gc_prologue();
    92.1 --- a/src/share/vm/runtime/vmStructs.cpp	Fri Oct 02 11:26:25 2009 -0700
    92.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Fri Oct 09 15:18:52 2009 -0700
    92.3 @@ -549,6 +549,7 @@
    92.4    /********************************/                                                                                                 \
    92.5                                                                                                                                       \
    92.6       static_field(CodeCache,                   _heap,                                         CodeHeap*)                             \
    92.7 +     static_field(CodeCache,                   _scavenge_root_nmethods,                       nmethod*)                              \
    92.8                                                                                                                                       \
    92.9    /*******************************/                                                                                                  \
   92.10    /* CodeHeap (NOTE: incomplete) */                                                                                                  \
   92.11 @@ -618,7 +619,9 @@
   92.12       static_field(nmethod,             _zombie_instruction_size,                      int)                                   \
   92.13    nonstatic_field(nmethod,             _method,                                       methodOop)                             \
   92.14    nonstatic_field(nmethod,             _entry_bci,                                    int)                                   \
   92.15 -  nonstatic_field(nmethod,             _link,                                         nmethod*)                              \
   92.16 +  nonstatic_field(nmethod,             _osr_link,                                     nmethod*)                              \
   92.17 +  nonstatic_field(nmethod,             _scavenge_root_link,                           nmethod*)                              \
   92.18 +  nonstatic_field(nmethod,             _scavenge_root_state,                          jbyte)                                 \
   92.19    nonstatic_field(nmethod,             _exception_offset,                             int)                                   \
   92.20    nonstatic_field(nmethod,             _deoptimize_offset,                            int)                                   \
   92.21    nonstatic_field(nmethod,             _orig_pc_offset,                               int)                                   \
    93.1 --- a/src/share/vm/runtime/vmThread.cpp	Fri Oct 02 11:26:25 2009 -0700
    93.2 +++ b/src/share/vm/runtime/vmThread.cpp	Fri Oct 09 15:18:52 2009 -0700
    93.3 @@ -619,8 +619,8 @@
    93.4  }
    93.5  
    93.6  
    93.7 -void VMThread::oops_do(OopClosure* f) {
    93.8 -  Thread::oops_do(f);
    93.9 +void VMThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   93.10 +  Thread::oops_do(f, cf);
   93.11    _vm_queue->oops_do(f);
   93.12  }
   93.13  
   93.14 @@ -652,5 +652,5 @@
   93.15  #endif
   93.16  
   93.17  void VMThread::verify() {
   93.18 -  oops_do(&VerifyOopClosure::verify_oop);
   93.19 +  oops_do(&VerifyOopClosure::verify_oop, NULL);
   93.20  }
    94.1 --- a/src/share/vm/runtime/vmThread.hpp	Fri Oct 02 11:26:25 2009 -0700
    94.2 +++ b/src/share/vm/runtime/vmThread.hpp	Fri Oct 09 15:18:52 2009 -0700
    94.3 @@ -121,7 +121,7 @@
    94.4    static VMThread* vm_thread()                    { return _vm_thread; }
    94.5  
    94.6    // GC support
    94.7 -  void oops_do(OopClosure* f);
    94.8 +  void oops_do(OopClosure* f, CodeBlobClosure* cf);
    94.9  
   94.10    // Debugging
   94.11    void print_on(outputStream* st) const;
    95.1 --- a/src/share/vm/utilities/debug.cpp	Fri Oct 02 11:26:25 2009 -0700
    95.2 +++ b/src/share/vm/utilities/debug.cpp	Fri Oct 09 15:18:52 2009 -0700
    95.3 @@ -702,11 +702,14 @@
    95.4    tty->print_cr("Searching strong roots:");
    95.5    Universe::oops_do(&lookFor, false);
    95.6    JNIHandles::oops_do(&lookFor);   // Global (strong) JNI handles
    95.7 -  Threads::oops_do(&lookFor);
    95.8 +  Threads::oops_do(&lookFor, NULL);
    95.9    ObjectSynchronizer::oops_do(&lookFor);
   95.10    //FlatProfiler::oops_do(&lookFor);
   95.11    SystemDictionary::oops_do(&lookFor);
   95.12  
   95.13 +  tty->print_cr("Searching code cache:");
   95.14 +  CodeCache::oops_do(&lookFor);
   95.15 +
   95.16    tty->print_cr("Done.");
   95.17  }
   95.18  
    96.1 --- a/test/compiler/6823453/Test.java	Fri Oct 02 11:26:25 2009 -0700
    96.2 +++ b/test/compiler/6823453/Test.java	Fri Oct 09 15:18:52 2009 -0700
    96.3 @@ -26,7 +26,7 @@
    96.4   * @test
    96.5   * @bug 6823453
    96.6   * @summary DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
    96.7 - * @run main/othervm -Xcomp -XX:CompileOnly=Test -XX:+DeoptimizeALot Test
    96.8 + * @run main/othervm -Xcomp -XX:+IgnoreUnrecognizedVMOptions -XX:CompileOnly=Test -XX:+DeoptimizeALot Test
    96.9   */
   96.10  
   96.11  public class Test {
    97.1 --- a/test/compiler/6833129/Test.java	Fri Oct 02 11:26:25 2009 -0700
    97.2 +++ b/test/compiler/6833129/Test.java	Fri Oct 09 15:18:52 2009 -0700
    97.3 @@ -25,7 +25,7 @@
    97.4   * @test
    97.5   * @bug 6833129
    97.6   * @summary Object.clone() and Arrays.copyOf ignore coping with -XX:+DeoptimizeALot
    97.7 - * @run main/othervm -Xbatch -XX:+DeoptimizeALot Test
    97.8 + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot Test
    97.9   */
   97.10  
   97.11  public class Test{
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/test/compiler/6875866/Test.java	Fri Oct 09 15:18:52 2009 -0700
    98.3 @@ -0,0 +1,46 @@
    98.4 +/*
    98.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    98.7 + *
    98.8 + * This code is free software; you can redistribute it and/or modify it
    98.9 + * under the terms of the GNU General Public License version 2 only, as
   98.10 + * published by the Free Software Foundation.
   98.11 + *
   98.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   98.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   98.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   98.15 + * version 2 for more details (a copy is included in the LICENSE file that
   98.16 + * accompanied this code).
   98.17 + *
   98.18 + * You should have received a copy of the GNU General Public License version
   98.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   98.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   98.21 + *
   98.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   98.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   98.24 + * have any questions.
   98.25 + */
   98.26 +
   98.27 +/**
   98.28 + * @test
   98.29 + * @bug 6875866
   98.30 + * @summary Intrinsic for String.indexOf() is broken on x86 with SSE4.2
   98.31 + *
   98.32 + * @run main/othervm -Xcomp Test
   98.33 + */
   98.34 +
   98.35 +public class Test {
   98.36 +
   98.37 +  static int IndexOfTest(String str) {
   98.38 +    return str.indexOf("11111xx1x");
   98.39 +  }
   98.40 +
   98.41 +  public static void main(String args[]) {
   98.42 +    String str = "11111xx11111xx1x";
   98.43 +    int idx = IndexOfTest(str);
   98.44 +    System.out.println("IndexOf = " + idx);
   98.45 +    if (idx != 7) {
   98.46 +      System.exit(97);
   98.47 +    }
   98.48 +  }
   98.49 +}
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/test/compiler/6877254/Test.java	Fri Oct 09 15:18:52 2009 -0700
    99.3 @@ -0,0 +1,51 @@
    99.4 +/*
    99.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    99.7 + *
    99.8 + * This code is free software; you can redistribute it and/or modify it
    99.9 + * under the terms of the GNU General Public License version 2 only, as
   99.10 + * published by the Free Software Foundation.
   99.11 + *
   99.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   99.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   99.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   99.15 + * version 2 for more details (a copy is included in the LICENSE file that
   99.16 + * accompanied this code).
   99.17 + *
   99.18 + * You should have received a copy of the GNU General Public License version
   99.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   99.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   99.21 + *
   99.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   99.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   99.24 + * have any questions.
   99.25 + */
   99.26 +
   99.27 +/**
   99.28 + * @test
   99.29 + * @bug 6877254
   99.30 + * @summary Implement StoreCMNode::Ideal to promote its OopStore above the MergeMem
   99.31 + *
   99.32 + * @run main/othervm -server -Xcomp -XX:+UseConcMarkSweepGC Test
   99.33 + */
   99.34 +
   99.35 +public class Test {
   99.36 +    static byte var_1;
   99.37 +    static String var_2 = "";
   99.38 +    static byte var_3;
   99.39 +    static float var_4 = 0;
   99.40 +
   99.41 +    public static void main(String[] args) {
   99.42 +        int i = 0;
   99.43 +
   99.44 +        for (String var_tmp = var_2; i < 11; var_1 = 0, i++) {
   99.45 +            var_2 = var_2;
   99.46 +            var_4 *= (var_4 *= (var_3 = 0));
   99.47 +        }
   99.48 +
   99.49 +        System.out.println("var_1 = " + var_1);
   99.50 +        System.out.println("var_2 = " + var_2);
   99.51 +        System.out.println("var_3 = " + var_3);
   99.52 +        System.out.println("var_4 = " + var_4);
   99.53 +    }
   99.54 +}

mercurial