Merge

Thu, 02 Apr 2009 17:01:00 -0700

author
trims
date
Thu, 02 Apr 2009 17:01:00 -0700
changeset 1121
a9d9d7e06593
parent 1098
032c6af894da
parent 1120
4e35bfab60a5
child 1122
aa3a6f3eaa43

Merge

     1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/StubRoutines.java	Wed Apr 01 22:31:26 2009 -0700
     1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/StubRoutines.java	Thu Apr 02 17:01:00 2009 -0700
     1.3 @@ -46,12 +46,18 @@
     1.4      Type type = db.lookupType("StubRoutines");
     1.5  
     1.6      callStubReturnAddressField = type.getAddressField("_call_stub_return_address");
     1.7 -    // Only some platforms have specif return from compiled to call_stub
     1.8 +    // Only some platforms have specific return from compiled to call_stub
     1.9      try {
    1.10 -      callStubCompiledReturnAddressField = type.getAddressField("_call_stub_compiled_return");
    1.11 +      type = db.lookupType("StubRoutines::x86");
    1.12 +      if (type != null) {
    1.13 +        callStubCompiledReturnAddressField = type.getAddressField("_call_stub_compiled_return");
    1.14 +      }
    1.15      } catch (RuntimeException re) {
    1.16        callStubCompiledReturnAddressField = null;
    1.17      }
    1.18 +    if (callStubCompiledReturnAddressField == null && VM.getVM().getCPU().equals("x86")) {
    1.19 +      throw new InternalError("Missing definition for _call_stub_compiled_return");
    1.20 +    }
    1.21    }
    1.22  
    1.23    public StubRoutines() {
     2.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Apr 01 22:31:26 2009 -0700
     2.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Apr 02 17:01:00 2009 -0700
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
     2.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -2615,12 +2615,12 @@
    2.11    }
    2.12  }
    2.13  
    2.14 -RegisterConstant MacroAssembler::delayed_value(intptr_t* delayed_value_addr,
    2.15 -                                               Register tmp,
    2.16 -                                               int offset) {
    2.17 +RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
    2.18 +                                                      Register tmp,
    2.19 +                                                      int offset) {
    2.20    intptr_t value = *delayed_value_addr;
    2.21    if (value != 0)
    2.22 -    return RegisterConstant(value + offset);
    2.23 +    return RegisterOrConstant(value + offset);
    2.24  
    2.25    // load indirectly to solve generation ordering problem
    2.26    Address a(tmp, (address) delayed_value_addr);
    2.27 @@ -2634,11 +2634,11 @@
    2.28    if (offset != 0)
    2.29      add(tmp, offset, tmp);
    2.30  
    2.31 -  return RegisterConstant(tmp);
    2.32 +  return RegisterOrConstant(tmp);
    2.33  }
    2.34  
    2.35  
    2.36 -void MacroAssembler::regcon_inc_ptr( RegisterConstant& dest, RegisterConstant src, Register temp ) {
    2.37 +void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
    2.38    assert(dest.register_or_noreg() != G0, "lost side effect");
    2.39    if ((src.is_constant() && src.as_constant() == 0) ||
    2.40        (src.is_register() && src.as_register() == G0)) {
    2.41 @@ -2647,15 +2647,15 @@
    2.42      add(dest.as_register(), ensure_rs2(src, temp), dest.as_register());
    2.43    } else if (src.is_constant()) {
    2.44      intptr_t res = dest.as_constant() + src.as_constant();
    2.45 -    dest = RegisterConstant(res); // side effect seen by caller
    2.46 +    dest = RegisterOrConstant(res); // side effect seen by caller
    2.47    } else {
    2.48      assert(temp != noreg, "cannot handle constant += register");
    2.49      add(src.as_register(), ensure_rs2(dest, temp), temp);
    2.50 -    dest = RegisterConstant(temp); // side effect seen by caller
    2.51 +    dest = RegisterOrConstant(temp); // side effect seen by caller
    2.52    }
    2.53  }
    2.54  
    2.55 -void MacroAssembler::regcon_sll_ptr( RegisterConstant& dest, RegisterConstant src, Register temp ) {
    2.56 +void MacroAssembler::regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
    2.57    assert(dest.register_or_noreg() != G0, "lost side effect");
    2.58    if (!is_simm13(src.constant_or_zero()))
    2.59      src = (src.as_constant() & 0xFF);
    2.60 @@ -2666,12 +2666,12 @@
    2.61      sll_ptr(dest.as_register(), src, dest.as_register());
    2.62    } else if (src.is_constant()) {
    2.63      intptr_t res = dest.as_constant() << src.as_constant();
    2.64 -    dest = RegisterConstant(res); // side effect seen by caller
    2.65 +    dest = RegisterOrConstant(res); // side effect seen by caller
    2.66    } else {
    2.67      assert(temp != noreg, "cannot handle constant <<= register");
    2.68      set(dest.as_constant(), temp);
    2.69      sll_ptr(temp, src, temp);
    2.70 -    dest = RegisterConstant(temp); // side effect seen by caller
    2.71 +    dest = RegisterOrConstant(temp); // side effect seen by caller
    2.72    }
    2.73  }
    2.74  
    2.75 @@ -2683,7 +2683,7 @@
    2.76  // On failure, execution transfers to the given label.
    2.77  void MacroAssembler::lookup_interface_method(Register recv_klass,
    2.78                                               Register intf_klass,
    2.79 -                                             RegisterConstant itable_index,
    2.80 +                                             RegisterOrConstant itable_index,
    2.81                                               Register method_result,
    2.82                                               Register scan_temp,
    2.83                                               Register sethi_temp,
    2.84 @@ -2720,7 +2720,7 @@
    2.85    add(recv_klass, scan_temp, scan_temp);
    2.86  
    2.87    // Adjust recv_klass by scaled itable_index, so we can free itable_index.
    2.88 -  RegisterConstant itable_offset = itable_index;
    2.89 +  RegisterOrConstant itable_offset = itable_index;
    2.90    regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
    2.91    regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
    2.92    add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass);
    2.93 @@ -2805,7 +2805,7 @@
    2.94                                                     Label* L_success,
    2.95                                                     Label* L_failure,
    2.96                                                     Label* L_slow_path,
    2.97 -                                        RegisterConstant super_check_offset,
    2.98 +                                        RegisterOrConstant super_check_offset,
    2.99                                          Register instanceof_hack) {
   2.100    int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
   2.101                     Klass::secondary_super_cache_offset_in_bytes());
   2.102 @@ -2867,7 +2867,7 @@
   2.103    if (must_load_sco) {
   2.104      // The super check offset is always positive...
   2.105      lduw(super_klass, sco_offset, temp2_reg);
   2.106 -    super_check_offset = RegisterConstant(temp2_reg);
   2.107 +    super_check_offset = RegisterOrConstant(temp2_reg);
   2.108    }
   2.109    ld_ptr(sub_klass, super_check_offset, temp_reg);
   2.110    cmp(super_klass, temp_reg);
   2.111 @@ -4234,7 +4234,6 @@
   2.112  static jint num_ct_writes = 0;
   2.113  static jint num_ct_writes_filtered_in_hr = 0;
   2.114  static jint num_ct_writes_filtered_null = 0;
   2.115 -static jint num_ct_writes_filtered_pop = 0;
   2.116  static G1CollectedHeap* g1 = NULL;
   2.117  
   2.118  static Thread* count_ct_writes(void* filter_val, void* new_val) {
   2.119 @@ -4247,25 +4246,19 @@
   2.120      if (g1 == NULL) {
   2.121        g1 = G1CollectedHeap::heap();
   2.122      }
   2.123 -    if ((HeapWord*)new_val < g1->popular_object_boundary()) {
   2.124 -      Atomic::inc(&num_ct_writes_filtered_pop);
   2.125 -    }
   2.126    }
   2.127    if ((num_ct_writes % 1000000) == 0) {
   2.128      jint num_ct_writes_filtered =
   2.129        num_ct_writes_filtered_in_hr +
   2.130 -      num_ct_writes_filtered_null +
   2.131 -      num_ct_writes_filtered_pop;
   2.132 +      num_ct_writes_filtered_null;
   2.133  
   2.134      tty->print_cr("%d potential CT writes: %5.2f%% filtered\n"
   2.135 -                  "   (%5.2f%% intra-HR, %5.2f%% null, %5.2f%% popular).",
   2.136 +                  "   (%5.2f%% intra-HR, %5.2f%% null).",
   2.137                    num_ct_writes,
   2.138                    100.0*(float)num_ct_writes_filtered/(float)num_ct_writes,
   2.139                    100.0*(float)num_ct_writes_filtered_in_hr/
   2.140                    (float)num_ct_writes,
   2.141                    100.0*(float)num_ct_writes_filtered_null/
   2.142 -                  (float)num_ct_writes,
   2.143 -                  100.0*(float)num_ct_writes_filtered_pop/
   2.144                    (float)num_ct_writes);
   2.145    }
   2.146    return Thread::current();
   2.147 @@ -4472,7 +4465,7 @@
   2.148  }
   2.149  
   2.150  // Loading values by size and signed-ness
   2.151 -void MacroAssembler::load_sized_value(Register s1, RegisterConstant s2, Register d,
   2.152 +void MacroAssembler::load_sized_value(Register s1, RegisterOrConstant s2, Register d,
   2.153                                        int size_in_bytes, bool is_signed) {
   2.154    switch (size_in_bytes ^ (is_signed ? -1 : 0)) {
   2.155    case ~8:  // fall through:
     3.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Apr 01 22:31:26 2009 -0700
     3.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Apr 02 17:01:00 2009 -0700
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -1088,8 +1088,8 @@
    3.11    inline void add(    Register s1, Register s2, Register d );
    3.12    inline void add(    Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none);
    3.13    inline void add(    Register s1, int simm13a, Register d, RelocationHolder const& rspec);
    3.14 -  inline void add(    Register s1, RegisterConstant s2, Register d, int offset = 0);
    3.15 -  inline void add(    const Address&  a,              Register d, int offset = 0);
    3.16 +  inline void add(    Register s1, RegisterOrConstant s2, Register d, int offset = 0);
    3.17 +  inline void add(    const Address&  a,                  Register d, int offset = 0);
    3.18  
    3.19    void addcc(  Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3  | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
    3.20    void addcc(  Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3  | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
    3.21 @@ -1305,15 +1305,15 @@
    3.22    inline void ld(   const Address& a, Register d, int offset = 0 );
    3.23    inline void ldd(  const Address& a, Register d, int offset = 0 );
    3.24  
    3.25 -  inline void ldub(  Register s1, RegisterConstant s2, Register d );
    3.26 -  inline void ldsb(  Register s1, RegisterConstant s2, Register d );
    3.27 -  inline void lduh(  Register s1, RegisterConstant s2, Register d );
    3.28 -  inline void ldsh(  Register s1, RegisterConstant s2, Register d );
    3.29 -  inline void lduw(  Register s1, RegisterConstant s2, Register d );
    3.30 -  inline void ldsw(  Register s1, RegisterConstant s2, Register d );
    3.31 -  inline void ldx(   Register s1, RegisterConstant s2, Register d );
    3.32 -  inline void ld(    Register s1, RegisterConstant s2, Register d );
    3.33 -  inline void ldd(   Register s1, RegisterConstant s2, Register d );
    3.34 +  inline void ldub(  Register s1, RegisterOrConstant s2, Register d );
    3.35 +  inline void ldsb(  Register s1, RegisterOrConstant s2, Register d );
    3.36 +  inline void lduh(  Register s1, RegisterOrConstant s2, Register d );
    3.37 +  inline void ldsh(  Register s1, RegisterOrConstant s2, Register d );
    3.38 +  inline void lduw(  Register s1, RegisterOrConstant s2, Register d );
    3.39 +  inline void ldsw(  Register s1, RegisterOrConstant s2, Register d );
    3.40 +  inline void ldx(   Register s1, RegisterOrConstant s2, Register d );
    3.41 +  inline void ld(    Register s1, RegisterOrConstant s2, Register d );
    3.42 +  inline void ldd(   Register s1, RegisterOrConstant s2, Register d );
    3.43  
    3.44    // pp 177
    3.45  
    3.46 @@ -1535,12 +1535,12 @@
    3.47    inline void st(   Register d, const Address& a, int offset = 0 );
    3.48    inline void std(  Register d, const Address& a, int offset = 0 );
    3.49  
    3.50 -  inline void stb(  Register d, Register s1, RegisterConstant s2 );
    3.51 -  inline void sth(  Register d, Register s1, RegisterConstant s2 );
    3.52 -  inline void stw(  Register d, Register s1, RegisterConstant s2 );
    3.53 -  inline void stx(  Register d, Register s1, RegisterConstant s2 );
    3.54 -  inline void std(  Register d, Register s1, RegisterConstant s2 );
    3.55 -  inline void st(   Register d, Register s1, RegisterConstant s2 );
    3.56 +  inline void stb(  Register d, Register s1, RegisterOrConstant s2 );
    3.57 +  inline void sth(  Register d, Register s1, RegisterOrConstant s2 );
    3.58 +  inline void stw(  Register d, Register s1, RegisterOrConstant s2 );
    3.59 +  inline void stx(  Register d, Register s1, RegisterOrConstant s2 );
    3.60 +  inline void std(  Register d, Register s1, RegisterOrConstant s2 );
    3.61 +  inline void st(   Register d, Register s1, RegisterOrConstant s2 );
    3.62  
    3.63    // pp 177
    3.64  
    3.65 @@ -1859,7 +1859,7 @@
    3.66    // Functions for isolating 64 bit shifts for LP64
    3.67    inline void sll_ptr( Register s1, Register s2, Register d );
    3.68    inline void sll_ptr( Register s1, int imm6a,   Register d );
    3.69 -  inline void sll_ptr( Register s1, RegisterConstant s2, Register d );
    3.70 +  inline void sll_ptr( Register s1, RegisterOrConstant s2, Register d );
    3.71    inline void srl_ptr( Register s1, Register s2, Register d );
    3.72    inline void srl_ptr( Register s1, int imm6a,   Register d );
    3.73  
    3.74 @@ -1965,26 +1965,26 @@
    3.75    // st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's
    3.76    inline void ld_ptr(   Register s1, Register s2, Register d );
    3.77    inline void ld_ptr(   Register s1, int simm13a, Register d);
    3.78 -  inline void ld_ptr(   Register s1, RegisterConstant s2, Register d );
    3.79 +  inline void ld_ptr(   Register s1, RegisterOrConstant s2, Register d );
    3.80    inline void ld_ptr(  const Address& a, Register d, int offset = 0 );
    3.81    inline void st_ptr(  Register d, Register s1, Register s2 );
    3.82    inline void st_ptr(  Register d, Register s1, int simm13a);
    3.83 -  inline void st_ptr(  Register d, Register s1, RegisterConstant s2 );
    3.84 +  inline void st_ptr(  Register d, Register s1, RegisterOrConstant s2 );
    3.85    inline void st_ptr(  Register d, const Address& a, int offset = 0 );
    3.86  
    3.87    // ld_long will perform ld for 32 bit VM's and ldx for 64 bit VM's
    3.88    // st_long will perform st for 32 bit VM's and stx for 64 bit VM's
    3.89    inline void ld_long( Register s1, Register s2, Register d );
    3.90    inline void ld_long( Register s1, int simm13a, Register d );
    3.91 -  inline void ld_long( Register s1, RegisterConstant s2, Register d );
    3.92 +  inline void ld_long( Register s1, RegisterOrConstant s2, Register d );
    3.93    inline void ld_long( const Address& a, Register d, int offset = 0 );
    3.94    inline void st_long( Register d, Register s1, Register s2 );
    3.95    inline void st_long( Register d, Register s1, int simm13a );
    3.96 -  inline void st_long( Register d, Register s1, RegisterConstant s2 );
    3.97 +  inline void st_long( Register d, Register s1, RegisterOrConstant s2 );
    3.98    inline void st_long( Register d, const Address& a, int offset = 0 );
    3.99  
   3.100    // Loading values by size and signed-ness
   3.101 -  void load_sized_value(Register s1, RegisterConstant s2, Register d,
   3.102 +  void load_sized_value(Register s1, RegisterOrConstant s2, Register d,
   3.103                          int size_in_bytes, bool is_signed);
   3.104  
   3.105    // Helpers for address formation.
   3.106 @@ -1994,11 +1994,11 @@
   3.107    // is required, and becomes the result.
   3.108    // If dest is a register and src is a non-simm13 constant,
   3.109    // the temp argument is required, and is used to materialize the constant.
   3.110 -  void regcon_inc_ptr( RegisterConstant& dest, RegisterConstant src,
   3.111 +  void regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src,
   3.112                         Register temp = noreg );
   3.113 -  void regcon_sll_ptr( RegisterConstant& dest, RegisterConstant src,
   3.114 +  void regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src,
   3.115                         Register temp = noreg );
   3.116 -  RegisterConstant ensure_rs2(RegisterConstant rs2, Register sethi_temp) {
   3.117 +  RegisterOrConstant ensure_rs2(RegisterOrConstant rs2, Register sethi_temp) {
   3.118      guarantee(sethi_temp != noreg, "constant offset overflow");
   3.119      if (is_simm13(rs2.constant_or_zero()))
   3.120        return rs2;               // register or short constant
   3.121 @@ -2322,7 +2322,7 @@
   3.122    // interface method calling
   3.123    void lookup_interface_method(Register recv_klass,
   3.124                                 Register intf_klass,
   3.125 -                               RegisterConstant itable_index,
   3.126 +                               RegisterOrConstant itable_index,
   3.127                                 Register method_result,
   3.128                                 Register temp_reg, Register temp2_reg,
   3.129                                 Label& no_such_interface);
   3.130 @@ -2341,7 +2341,7 @@
   3.131                                       Label* L_success,
   3.132                                       Label* L_failure,
   3.133                                       Label* L_slow_path,
   3.134 -                RegisterConstant super_check_offset = RegisterConstant(-1),
   3.135 +                RegisterOrConstant super_check_offset = RegisterOrConstant(-1),
   3.136                  Register instanceof_hack = noreg);
   3.137  
   3.138    // The rest of the type check; must be wired to a corresponding fast path.
   3.139 @@ -2381,7 +2381,7 @@
   3.140    // stack overflow + shadow pages.  Clobbers tsp and scratch registers.
   3.141    void bang_stack_size(Register Rsize, Register Rtsp, Register Rscratch);
   3.142  
   3.143 -  virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp, int offset);
   3.144 +  virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset);
   3.145  
   3.146    void verify_tlab();
   3.147  
     4.1 --- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Wed Apr 01 22:31:26 2009 -0700
     4.2 +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Thu Apr 02 17:01:00 2009 -0700
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
     4.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -143,45 +143,45 @@
    4.11  inline void Assembler::ld(  Register s1, int simm13a, Register d) { lduw( s1, simm13a, d); }
    4.12  #endif
    4.13  
    4.14 -inline void Assembler::ldub(  Register s1, RegisterConstant s2, Register d) {
    4.15 +inline void Assembler::ldub(  Register s1, RegisterOrConstant s2, Register d) {
    4.16    if (s2.is_register())  ldsb(s1, s2.as_register(), d);
    4.17    else                   ldsb(s1, s2.as_constant(), d);
    4.18  }
    4.19 -inline void Assembler::ldsb(  Register s1, RegisterConstant s2, Register d) {
    4.20 +inline void Assembler::ldsb(  Register s1, RegisterOrConstant s2, Register d) {
    4.21    if (s2.is_register())  ldsb(s1, s2.as_register(), d);
    4.22    else                   ldsb(s1, s2.as_constant(), d);
    4.23  }
    4.24 -inline void Assembler::lduh(  Register s1, RegisterConstant s2, Register d) {
    4.25 +inline void Assembler::lduh(  Register s1, RegisterOrConstant s2, Register d) {
    4.26    if (s2.is_register())  ldsh(s1, s2.as_register(), d);
    4.27    else                   ldsh(s1, s2.as_constant(), d);
    4.28  }
    4.29 -inline void Assembler::ldsh(  Register s1, RegisterConstant s2, Register d) {
    4.30 +inline void Assembler::ldsh(  Register s1, RegisterOrConstant s2, Register d) {
    4.31    if (s2.is_register())  ldsh(s1, s2.as_register(), d);
    4.32    else                   ldsh(s1, s2.as_constant(), d);
    4.33  }
    4.34 -inline void Assembler::lduw(  Register s1, RegisterConstant s2, Register d) {
    4.35 +inline void Assembler::lduw(  Register s1, RegisterOrConstant s2, Register d) {
    4.36    if (s2.is_register())  ldsw(s1, s2.as_register(), d);
    4.37    else                   ldsw(s1, s2.as_constant(), d);
    4.38  }
    4.39 -inline void Assembler::ldsw(  Register s1, RegisterConstant s2, Register d) {
    4.40 +inline void Assembler::ldsw(  Register s1, RegisterOrConstant s2, Register d) {
    4.41    if (s2.is_register())  ldsw(s1, s2.as_register(), d);
    4.42    else                   ldsw(s1, s2.as_constant(), d);
    4.43  }
    4.44 -inline void Assembler::ldx(   Register s1, RegisterConstant s2, Register d) {
    4.45 +inline void Assembler::ldx(   Register s1, RegisterOrConstant s2, Register d) {
    4.46    if (s2.is_register())  ldx(s1, s2.as_register(), d);
    4.47    else                   ldx(s1, s2.as_constant(), d);
    4.48  }
    4.49 -inline void Assembler::ld(    Register s1, RegisterConstant s2, Register d) {
    4.50 +inline void Assembler::ld(    Register s1, RegisterOrConstant s2, Register d) {
    4.51    if (s2.is_register())  ld(s1, s2.as_register(), d);
    4.52    else                   ld(s1, s2.as_constant(), d);
    4.53  }
    4.54 -inline void Assembler::ldd(   Register s1, RegisterConstant s2, Register d) {
    4.55 +inline void Assembler::ldd(   Register s1, RegisterOrConstant s2, Register d) {
    4.56    if (s2.is_register())  ldd(s1, s2.as_register(), d);
    4.57    else                   ldd(s1, s2.as_constant(), d);
    4.58  }
    4.59  
    4.60  // form effective addresses this way:
    4.61 -inline void Assembler::add(   Register s1, RegisterConstant s2, Register d, int offset) {
    4.62 +inline void Assembler::add(   Register s1, RegisterOrConstant s2, Register d, int offset) {
    4.63    if (s2.is_register())  add(s1, s2.as_register(), d);
    4.64    else                 { add(s1, s2.as_constant() + offset, d); offset = 0; }
    4.65    if (offset != 0)       add(d,  offset,                    d);
    4.66 @@ -243,23 +243,23 @@
    4.67  inline void Assembler::st(  Register d, Register s1, Register s2) { stw(d, s1, s2); }
    4.68  inline void Assembler::st(  Register d, Register s1, int simm13a) { stw(d, s1, simm13a); }
    4.69  
    4.70 -inline void Assembler::stb(  Register d, Register s1, RegisterConstant s2) {
    4.71 +inline void Assembler::stb(  Register d, Register s1, RegisterOrConstant s2) {
    4.72    if (s2.is_register())  stb(d, s1, s2.as_register());
    4.73    else                   stb(d, s1, s2.as_constant());
    4.74  }
    4.75 -inline void Assembler::sth(  Register d, Register s1, RegisterConstant s2) {
    4.76 +inline void Assembler::sth(  Register d, Register s1, RegisterOrConstant s2) {
    4.77    if (s2.is_register())  sth(d, s1, s2.as_register());
    4.78    else                   sth(d, s1, s2.as_constant());
    4.79  }
    4.80 -inline void Assembler::stx(  Register d, Register s1, RegisterConstant s2) {
    4.81 +inline void Assembler::stx(  Register d, Register s1, RegisterOrConstant s2) {
    4.82    if (s2.is_register())  stx(d, s1, s2.as_register());
    4.83    else                   stx(d, s1, s2.as_constant());
    4.84  }
    4.85 -inline void Assembler::std( Register d, Register s1, RegisterConstant s2) {
    4.86 +inline void Assembler::std( Register d, Register s1, RegisterOrConstant s2) {
    4.87    if (s2.is_register())  std(d, s1, s2.as_register());
    4.88    else                   std(d, s1, s2.as_constant());
    4.89  }
    4.90 -inline void Assembler::st(  Register d, Register s1, RegisterConstant s2) {
    4.91 +inline void Assembler::st(  Register d, Register s1, RegisterOrConstant s2) {
    4.92    if (s2.is_register())  st(d, s1, s2.as_register());
    4.93    else                   st(d, s1, s2.as_constant());
    4.94  }
    4.95 @@ -308,7 +308,7 @@
    4.96  #endif
    4.97  }
    4.98  
    4.99 -inline void MacroAssembler::ld_ptr( Register s1, RegisterConstant s2, Register d ) {
   4.100 +inline void MacroAssembler::ld_ptr( Register s1, RegisterOrConstant s2, Register d ) {
   4.101  #ifdef _LP64
   4.102    Assembler::ldx( s1, s2, d);
   4.103  #else
   4.104 @@ -340,7 +340,7 @@
   4.105  #endif
   4.106  }
   4.107  
   4.108 -inline void MacroAssembler::st_ptr( Register d, Register s1, RegisterConstant s2 ) {
   4.109 +inline void MacroAssembler::st_ptr( Register d, Register s1, RegisterOrConstant s2 ) {
   4.110  #ifdef _LP64
   4.111    Assembler::stx( d, s1, s2);
   4.112  #else
   4.113 @@ -373,7 +373,7 @@
   4.114  #endif
   4.115  }
   4.116  
   4.117 -inline void MacroAssembler::ld_long( Register s1, RegisterConstant s2, Register d ) {
   4.118 +inline void MacroAssembler::ld_long( Register s1, RegisterOrConstant s2, Register d ) {
   4.119  #ifdef _LP64
   4.120    Assembler::ldx(s1, s2, d);
   4.121  #else
   4.122 @@ -405,7 +405,7 @@
   4.123  #endif
   4.124  }
   4.125  
   4.126 -inline void MacroAssembler::st_long( Register d, Register s1, RegisterConstant s2 ) {
   4.127 +inline void MacroAssembler::st_long( Register d, Register s1, RegisterOrConstant s2 ) {
   4.128  #ifdef _LP64
   4.129    Assembler::stx(d, s1, s2);
   4.130  #else
   4.131 @@ -455,7 +455,7 @@
   4.132  #endif
   4.133  }
   4.134  
   4.135 -inline void MacroAssembler::sll_ptr( Register s1, RegisterConstant s2, Register d ) {
   4.136 +inline void MacroAssembler::sll_ptr( Register s1, RegisterOrConstant s2, Register d ) {
   4.137    if (s2.is_register())  sll_ptr(s1, s2.as_register(), d);
   4.138    else                   sll_ptr(s1, s2.as_constant(), d);
   4.139  }
     5.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Apr 01 22:31:26 2009 -0700
     5.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Apr 02 17:01:00 2009 -0700
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
     5.6 + * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -2489,7 +2489,7 @@
    5.11          __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg,
    5.12                                           (need_slow_path ? &done : NULL),
    5.13                                           stub->entry(), NULL,
    5.14 -                                         RegisterConstant(k->super_check_offset()));
    5.15 +                                         RegisterOrConstant(k->super_check_offset()));
    5.16        } else {
    5.17          // perform the fast part of the checking logic
    5.18          __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7,
    5.19 @@ -2550,14 +2550,14 @@
    5.20          __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, noreg,
    5.21                                           (need_slow_path ? &done : NULL),
    5.22                                           (need_slow_path ? &done : NULL), NULL,
    5.23 -                                         RegisterConstant(k->super_check_offset()),
    5.24 +                                         RegisterOrConstant(k->super_check_offset()),
    5.25                                           dst);
    5.26        } else {
    5.27          assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers");
    5.28          // perform the fast part of the checking logic
    5.29          __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, dst,
    5.30                                           &done, &done, NULL,
    5.31 -                                         RegisterConstant(-1),
    5.32 +                                         RegisterOrConstant(-1),
    5.33                                           dst);
    5.34        }
    5.35        if (need_slow_path) {
     6.1 --- a/src/cpu/sparc/vm/globals_sparc.hpp	Wed Apr 01 22:31:26 2009 -0700
     6.2 +++ b/src/cpu/sparc/vm/globals_sparc.hpp	Thu Apr 02 17:01:00 2009 -0700
     6.3 @@ -46,6 +46,7 @@
     6.4  define_pd_global(uintx, NewSize, ScaleForWordSize((2048 * K) + (2 * (64 * K))));
     6.5  define_pd_global(intx,  SurvivorRatio,         8);
     6.6  define_pd_global(intx,  InlineFrequencyCount,  50);  // we can use more inlining on the SPARC
     6.7 +define_pd_global(intx,  InlineSmallCode,       1500);
     6.8  #ifdef _LP64
     6.9  // Stack slots are 2X larger in LP64 than in the 32 bit VM.
    6.10  define_pd_global(intx,  ThreadStackSize,       1024);
     7.1 --- a/src/cpu/sparc/vm/sparc.ad	Wed Apr 01 22:31:26 2009 -0700
     7.2 +++ b/src/cpu/sparc/vm/sparc.ad	Thu Apr 02 17:01:00 2009 -0700
     7.3 @@ -3003,6 +3003,202 @@
     7.4      __ bind(Ldone);
     7.5    %}
     7.6  
     7.7 +enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
     7.8 +    Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
     7.9 +    MacroAssembler _masm(&cbuf);
    7.10 +
    7.11 +    Register   str1_reg = reg_to_register_object($str1$$reg);
    7.12 +    Register   str2_reg = reg_to_register_object($str2$$reg);
    7.13 +    Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
    7.14 +    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
    7.15 +    Register result_reg = reg_to_register_object($result$$reg);
    7.16 +
    7.17 +    // Get the first character position in both strings
    7.18 +    //         [8] char array, [12] offset, [16] count
    7.19 +    int  value_offset = java_lang_String:: value_offset_in_bytes();
    7.20 +    int offset_offset = java_lang_String::offset_offset_in_bytes();
    7.21 +    int  count_offset = java_lang_String:: count_offset_in_bytes();
    7.22 +
    7.23 +    // load str1 (jchar*) base address into tmp1_reg
    7.24 +    __ load_heap_oop(Address(str1_reg, 0,  value_offset), tmp1_reg);
    7.25 +    __ ld(Address(str1_reg, 0, offset_offset), result_reg);
    7.26 +    __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
    7.27 +    __    ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted
    7.28 +    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
    7.29 +    __    load_heap_oop(Address(str2_reg, 0,  value_offset), tmp2_reg); // hoisted
    7.30 +    __ add(result_reg, tmp1_reg, tmp1_reg);
    7.31 +
    7.32 +    // load str2 (jchar*) base address into tmp2_reg
    7.33 +    // __ ld_ptr(Address(str2_reg, 0,  value_offset), tmp2_reg); // hoisted
    7.34 +    __ ld(Address(str2_reg, 0, offset_offset), result_reg);
    7.35 +    __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
    7.36 +    __    ld(Address(str2_reg, 0, count_offset), str2_reg); // hoisted
    7.37 +    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
    7.38 +    __   cmp(str1_reg, str2_reg); // hoisted
    7.39 +    __ add(result_reg, tmp2_reg, tmp2_reg);
    7.40 +
    7.41 +    __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg);
    7.42 +    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
    7.43 +    __ delayed()->mov(G0, result_reg);    // not equal
    7.44 +
    7.45 +    __ br_zero(Assembler::equal, true, Assembler::pn, str1_reg, Ldone);
    7.46 +    __ delayed()->add(G0, 1, result_reg); //equals
    7.47 +
    7.48 +    __ cmp(tmp1_reg, tmp2_reg); //same string ?
    7.49 +    __ brx(Assembler::equal, true, Assembler::pn, Ldone);
    7.50 +    __ delayed()->add(G0, 1, result_reg);
    7.51 +
    7.52 +    //rename registers
    7.53 +    Register limit_reg =   str1_reg;
    7.54 +    Register  chr2_reg =   str2_reg;
    7.55 +    Register  chr1_reg = result_reg;
    7.56 +    // tmp{12} are the base pointers
    7.57 +
    7.58 +    //check for alignment and position the pointers to the ends
    7.59 +    __ or3(tmp1_reg, tmp2_reg, chr1_reg);
    7.60 +    __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
    7.61 +    __ br(Assembler::notZero, false, Assembler::pn, Lchar);
    7.62 +    __ delayed()->nop();
    7.63 +
    7.64 +    __ bind(Lword);
    7.65 +    __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2)
    7.66 +    __ andn(limit_reg, 0x3, limit_reg);
    7.67 +    __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
    7.68 +    __ delayed()->nop();
    7.69 +
    7.70 +    __ add(tmp1_reg, limit_reg, tmp1_reg);
    7.71 +    __ add(tmp2_reg, limit_reg, tmp2_reg);
    7.72 +    __ neg(limit_reg);
    7.73 +
    7.74 +    __ lduw(tmp1_reg, limit_reg, chr1_reg);
    7.75 +    __ bind(Lword_loop);
    7.76 +    __ lduw(tmp2_reg, limit_reg, chr2_reg);
    7.77 +    __ cmp(chr1_reg, chr2_reg);
    7.78 +    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
    7.79 +    __ delayed()->mov(G0, result_reg);
    7.80 +    __ inccc(limit_reg, 2*sizeof(jchar));
    7.81 +    // annul LDUW if branch i  s not taken to prevent access past end of string
    7.82 +    __ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
    7.83 +    __ delayed()->lduw(tmp1_reg, limit_reg, chr1_reg); // hoisted
    7.84 +
    7.85 +    __ bind(Lpost_word);
    7.86 +    __ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
    7.87 +    __ delayed()->add(G0, 1, result_reg);
    7.88 +
    7.89 +    __ lduh(tmp1_reg, 0, chr1_reg);
    7.90 +    __ lduh(tmp2_reg, 0, chr2_reg);
    7.91 +    __ cmp (chr1_reg, chr2_reg);
    7.92 +    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
    7.93 +    __ delayed()->mov(G0, result_reg);
    7.94 +    __ ba(false,Ldone);
    7.95 +    __ delayed()->add(G0, 1, result_reg);
    7.96 +
    7.97 +    __ bind(Lchar);
    7.98 +    __ add(tmp1_reg, limit_reg, tmp1_reg);
    7.99 +    __ add(tmp2_reg, limit_reg, tmp2_reg);
   7.100 +    __ neg(limit_reg); //negate count
   7.101 +
   7.102 +    __ lduh(tmp1_reg, limit_reg, chr1_reg);
   7.103 +    __ bind(Lchar_loop);
   7.104 +    __ lduh(tmp2_reg, limit_reg, chr2_reg);
   7.105 +    __ cmp(chr1_reg, chr2_reg);
   7.106 +    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.107 +    __ delayed()->mov(G0, result_reg); //not equal
   7.108 +    __ inccc(limit_reg, sizeof(jchar));
   7.109 +    // annul LDUH if branch is not taken to prevent access past end of string
   7.110 +    __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
   7.111 +    __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
   7.112 +
   7.113 +    __ add(G0, 1, result_reg);  //equal
   7.114 +
   7.115 +    __ bind(Ldone);
   7.116 +  %}
   7.117 +
   7.118 +enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
   7.119 +    Label Lvector, Ldone, Lloop;
   7.120 +    MacroAssembler _masm(&cbuf);
   7.121 +
   7.122 +    Register   ary1_reg = reg_to_register_object($ary1$$reg);
   7.123 +    Register   ary2_reg = reg_to_register_object($ary2$$reg);
   7.124 +    Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
   7.125 +    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
   7.126 +    Register result_reg = reg_to_register_object($result$$reg);
   7.127 +
   7.128 +    int length_offset  = arrayOopDesc::length_offset_in_bytes();
   7.129 +    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
   7.130 +
   7.131 +    // return true if the same array
   7.132 +    __ cmp(ary1_reg, ary2_reg);
   7.133 +    __ br(Assembler::equal, true, Assembler::pn, Ldone);
   7.134 +    __ delayed()->add(G0, 1, result_reg); // equal
   7.135 +
   7.136 +    __ br_null(ary1_reg, true, Assembler::pn, Ldone);
   7.137 +    __ delayed()->mov(G0, result_reg);    // not equal
   7.138 +
   7.139 +    __ br_null(ary2_reg, true, Assembler::pn, Ldone);
   7.140 +    __ delayed()->mov(G0, result_reg);    // not equal
   7.141 +
   7.142 +    //load the lengths of arrays
   7.143 +    __ ld(Address(ary1_reg, 0, length_offset), tmp1_reg);
   7.144 +    __ ld(Address(ary2_reg, 0, length_offset), tmp2_reg);
   7.145 +
   7.146 +    // return false if the two arrays are not equal length
   7.147 +    __ cmp(tmp1_reg, tmp2_reg);
   7.148 +    __ br(Assembler::notEqual, true, Assembler::pn, Ldone);
   7.149 +    __ delayed()->mov(G0, result_reg);     // not equal
   7.150 +
   7.151 +    __ br_zero(Assembler::zero, true, Assembler::pn, tmp1_reg, Ldone);
   7.152 +    __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
   7.153 +
   7.154 +    // load array addresses
   7.155 +    __ add(ary1_reg, base_offset, ary1_reg);
   7.156 +    __ add(ary2_reg, base_offset, ary2_reg);
   7.157 +
   7.158 +    // renaming registers
   7.159 +    Register chr1_reg  =  tmp2_reg;   // for characters in ary1
   7.160 +    Register chr2_reg  =  result_reg; // for characters in ary2
   7.161 +    Register limit_reg =  tmp1_reg;   // length
   7.162 +
   7.163 +    // set byte count
   7.164 +    __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
   7.165 +    __ andcc(limit_reg, 0x2, chr1_reg); //trailing character ?
   7.166 +    __ br(Assembler::zero, false, Assembler::pt, Lvector);
   7.167 +    __ delayed()->nop();
   7.168 +
   7.169 +    //compare the trailing char
   7.170 +    __ sub(limit_reg, sizeof(jchar), limit_reg);
   7.171 +    __ lduh(ary1_reg, limit_reg, chr1_reg);
   7.172 +    __ lduh(ary2_reg, limit_reg, chr2_reg);
   7.173 +    __ cmp(chr1_reg, chr2_reg);
   7.174 +    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
   7.175 +    __ delayed()->mov(G0, result_reg);     // not equal
   7.176 +
   7.177 +    // only one char ?
   7.178 +    __ br_zero(Assembler::zero, true, Assembler::pn, limit_reg, Ldone);
   7.179 +    __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
   7.180 +
   7.181 +    __ bind(Lvector);
   7.182 +    // Shift ary1_reg and ary2_reg to the end of the arrays, negate limit
   7.183 +    __ add(ary1_reg, limit_reg, ary1_reg);
   7.184 +    __ add(ary2_reg, limit_reg, ary2_reg);
   7.185 +    __ neg(limit_reg, limit_reg);
   7.186 +
   7.187 +    __ lduw(ary1_reg, limit_reg, chr1_reg);
   7.188 +    __ bind(Lloop);
   7.189 +    __ lduw(ary2_reg, limit_reg, chr2_reg);
   7.190 +    __ cmp(chr1_reg, chr2_reg);
   7.191 +    __ br(Assembler::notEqual, false, Assembler::pt, Ldone);
   7.192 +    __ delayed()->mov(G0, result_reg);     // not equal
   7.193 +    __ inccc(limit_reg, 2*sizeof(jchar));
   7.194 +    // annul LDUW if branch is not taken to prevent access past end of string
   7.195 +    __ br(Assembler::notZero, true, Assembler::pt, Lloop); //annul on taken
   7.196 +    __ delayed()->lduw(ary1_reg, limit_reg, chr1_reg); // hoisted
   7.197 +
   7.198 +    __ add(G0, 1, result_reg); // equals
   7.199 +
   7.200 +    __ bind(Ldone);
   7.201 +  %}
   7.202 +
   7.203    enc_class enc_rethrow() %{
   7.204      cbuf.set_inst_mark();
   7.205      Register temp_reg = G3;
   7.206 @@ -9015,6 +9211,25 @@
   7.207    ins_pipe(long_memory_op);
   7.208  %}
   7.209  
   7.210 +instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
   7.211 +                       o7RegI tmp3, flagsReg ccr) %{
   7.212 +  match(Set result (StrEquals str1 str2));
   7.213 +  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
   7.214 +  ins_cost(300);
   7.215 +  format %{ "String Equals $str1,$str2 -> $result" %}
   7.216 +  ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) );
   7.217 +  ins_pipe(long_memory_op);
   7.218 +%}
   7.219 +
   7.220 +instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
   7.221 +                        flagsReg ccr) %{
   7.222 +  match(Set result (AryEq ary1 ary2));
   7.223 +  effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
   7.224 +  ins_cost(300);
   7.225 +  format %{ "Array Equals $ary1,$ary2 -> $result" %}
   7.226 +  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
   7.227 +  ins_pipe(long_memory_op);
   7.228 +%}
   7.229  
   7.230  //---------- Population Count Instructions -------------------------------------
   7.231  
     8.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Apr 01 22:31:26 2009 -0700
     8.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Apr 02 17:01:00 2009 -0700
     8.3 @@ -817,21 +817,6 @@
     8.4    Label _atomic_add_stub;  // called from other stubs
     8.5  
     8.6  
     8.7 -  // Support for void OrderAccess::fence().
     8.8 -  //
     8.9 -  address generate_fence() {
    8.10 -    StubCodeMark mark(this, "StubRoutines", "fence");
    8.11 -    address start = __ pc();
    8.12 -
    8.13 -    __ membar(Assembler::Membar_mask_bits(Assembler::LoadLoad  | Assembler::LoadStore |
    8.14 -                                          Assembler::StoreLoad | Assembler::StoreStore));
    8.15 -    __ retl(false);
    8.16 -    __ delayed()->nop();
    8.17 -
    8.18 -    return start;
    8.19 -  }
    8.20 -
    8.21 -
    8.22    //------------------------------------------------------------------------------------------------------------------------
    8.23    // The following routine generates a subroutine to throw an asynchronous
    8.24    // UnknownError when an unsafe access gets a fault that could not be
    8.25 @@ -2861,7 +2846,6 @@
    8.26      StubRoutines::_atomic_cmpxchg_ptr_entry  = StubRoutines::_atomic_cmpxchg_entry;
    8.27      StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
    8.28      StubRoutines::_atomic_add_ptr_entry      = StubRoutines::_atomic_add_entry;
    8.29 -    StubRoutines::_fence_entry               = generate_fence();
    8.30  #endif  // COMPILER2 !=> _LP64
    8.31    }
    8.32  
     9.1 --- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Apr 01 22:31:26 2009 -0700
     9.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Apr 02 17:01:00 2009 -0700
     9.3 @@ -62,7 +62,7 @@
     9.4    if (is_niagara1()) {
     9.5      // Indirect branch is the same cost as direct
     9.6      if (FLAG_IS_DEFAULT(UseInlineCaches)) {
     9.7 -      UseInlineCaches         = false;
     9.8 +      FLAG_SET_DEFAULT(UseInlineCaches, false);
     9.9      }
    9.10  #ifdef _LP64
    9.11      // Single issue niagara1 is slower for CompressedOops
    9.12 @@ -79,15 +79,19 @@
    9.13  #ifdef COMPILER2
    9.14      // Indirect branch is the same cost as direct
    9.15      if (FLAG_IS_DEFAULT(UseJumpTables)) {
    9.16 -      UseJumpTables           = true;
    9.17 +      FLAG_SET_DEFAULT(UseJumpTables, true);
    9.18      }
    9.19      // Single-issue, so entry and loop tops are
    9.20      // aligned on a single instruction boundary
    9.21      if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
    9.22 -      InteriorEntryAlignment  = 4;
    9.23 +      FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
    9.24      }
    9.25      if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
    9.26 -      OptoLoopAlignment       = 4;
    9.27 +      FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
    9.28 +    }
    9.29 +    if (is_niagara1_plus() && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
    9.30 +      // Use smaller prefetch distance on N2
    9.31 +      FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
    9.32      }
    9.33  #endif
    9.34    }
    9.35 @@ -95,7 +99,7 @@
    9.36    // Use hardware population count instruction if available.
    9.37    if (has_hardware_popc()) {
    9.38      if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
    9.39 -      UsePopCountInstruction = true;
    9.40 +      FLAG_SET_DEFAULT(UsePopCountInstruction, true);
    9.41      }
    9.42    }
    9.43  
    10.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Wed Apr 01 22:31:26 2009 -0700
    10.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Apr 02 17:01:00 2009 -0700
    10.3 @@ -1438,26 +1438,12 @@
    10.4    }
    10.5  }
    10.6  
    10.7 -// Serializes memory.
    10.8 +// Emit mfence instruction
    10.9  void Assembler::mfence() {
   10.10 -    // Memory barriers are only needed on multiprocessors
   10.11 -  if (os::is_MP()) {
   10.12 -    if( LP64_ONLY(true ||) VM_Version::supports_sse2() ) {
   10.13 -      emit_byte( 0x0F );                // MFENCE; faster blows no regs
   10.14 -      emit_byte( 0xAE );
   10.15 -      emit_byte( 0xF0 );
   10.16 -    } else {
   10.17 -      // All usable chips support "locked" instructions which suffice
   10.18 -      // as barriers, and are much faster than the alternative of
   10.19 -      // using cpuid instruction. We use here a locked add [esp],0.
   10.20 -      // This is conveniently otherwise a no-op except for blowing
   10.21 -      // flags (which we save and restore.)
   10.22 -      pushf();                // Save eflags register
   10.23 -      lock();
   10.24 -      addl(Address(rsp, 0), 0);// Assert the lock# signal here
   10.25 -      popf();                 // Restore eflags register
   10.26 -    }
   10.27 -  }
   10.28 +  NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
   10.29 +  emit_byte( 0x0F );
   10.30 +  emit_byte( 0xAE );
   10.31 +  emit_byte( 0xF0 );
   10.32  }
   10.33  
   10.34  void Assembler::mov(Register dst, Register src) {
   10.35 @@ -2187,6 +2173,31 @@
   10.36    emit_arith(0x0B, 0xC0, dst, src);
   10.37  }
   10.38  
   10.39 +void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
   10.40 +  assert(VM_Version::supports_sse4_2(), "");
   10.41 +
   10.42 +  InstructionMark im(this);
   10.43 +  emit_byte(0x66);
   10.44 +  prefix(src, dst);
   10.45 +  emit_byte(0x0F);
   10.46 +  emit_byte(0x3A);
   10.47 +  emit_byte(0x61);
   10.48 +  emit_operand(dst, src);
   10.49 +  emit_byte(imm8);
   10.50 +}
   10.51 +
   10.52 +void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
   10.53 +  assert(VM_Version::supports_sse4_2(), "");
   10.54 +
   10.55 +  emit_byte(0x66);
   10.56 +  int encode = prefixq_and_encode(dst->encoding(), src->encoding());
   10.57 +  emit_byte(0x0F);
   10.58 +  emit_byte(0x3A);
   10.59 +  emit_byte(0x61);
   10.60 +  emit_byte(0xC0 | encode);
   10.61 +  emit_byte(imm8);
   10.62 +}
   10.63 +
   10.64  // generic
   10.65  void Assembler::pop(Register dst) {
   10.66    int encode = prefix_and_encode(dst->encoding());
   10.67 @@ -2344,6 +2355,29 @@
   10.68    emit_byte(shift);
   10.69  }
   10.70  
   10.71 +void Assembler::ptest(XMMRegister dst, Address src) {
   10.72 +  assert(VM_Version::supports_sse4_1(), "");
   10.73 +
   10.74 +  InstructionMark im(this);
   10.75 +  emit_byte(0x66);
   10.76 +  prefix(src, dst);
   10.77 +  emit_byte(0x0F);
   10.78 +  emit_byte(0x38);
   10.79 +  emit_byte(0x17);
   10.80 +  emit_operand(dst, src);
   10.81 +}
   10.82 +
   10.83 +void Assembler::ptest(XMMRegister dst, XMMRegister src) {
   10.84 +  assert(VM_Version::supports_sse4_1(), "");
   10.85 +
   10.86 +  emit_byte(0x66);
   10.87 +  int encode = prefixq_and_encode(dst->encoding(), src->encoding());
   10.88 +  emit_byte(0x0F);
   10.89 +  emit_byte(0x38);
   10.90 +  emit_byte(0x17);
   10.91 +  emit_byte(0xC0 | encode);
   10.92 +}
   10.93 +
   10.94  void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
   10.95    NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   10.96    emit_byte(0x66);
   10.97 @@ -7218,7 +7252,7 @@
   10.98  // On failure, execution transfers to the given label.
   10.99  void MacroAssembler::lookup_interface_method(Register recv_klass,
  10.100                                               Register intf_klass,
  10.101 -                                             RegisterConstant itable_index,
  10.102 +                                             RegisterOrConstant itable_index,
  10.103                                               Register method_result,
  10.104                                               Register scan_temp,
  10.105                                               Label& L_no_such_interface) {
  10.106 @@ -7303,7 +7337,7 @@
  10.107                                                     Label* L_success,
  10.108                                                     Label* L_failure,
  10.109                                                     Label* L_slow_path,
  10.110 -                                        RegisterConstant super_check_offset) {
  10.111 +                                        RegisterOrConstant super_check_offset) {
  10.112    assert_different_registers(sub_klass, super_klass, temp_reg);
  10.113    bool must_load_sco = (super_check_offset.constant_or_zero() == -1);
  10.114    if (super_check_offset.is_register()) {
  10.115 @@ -7352,7 +7386,7 @@
  10.116    if (must_load_sco) {
  10.117      // Positive movl does right thing on LP64.
  10.118      movl(temp_reg, super_check_offset_addr);
  10.119 -    super_check_offset = RegisterConstant(temp_reg);
  10.120 +    super_check_offset = RegisterOrConstant(temp_reg);
  10.121    }
  10.122    Address super_check_addr(sub_klass, super_check_offset, Address::times_1, 0);
  10.123    cmpptr(super_klass, super_check_addr); // load displayed supertype
  10.124 @@ -7550,12 +7584,12 @@
  10.125  }
  10.126  
  10.127  
  10.128 -RegisterConstant MacroAssembler::delayed_value(intptr_t* delayed_value_addr,
  10.129 -                                               Register tmp,
  10.130 -                                               int offset) {
  10.131 +RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
  10.132 +                                                      Register tmp,
  10.133 +                                                      int offset) {
  10.134    intptr_t value = *delayed_value_addr;
  10.135    if (value != 0)
  10.136 -    return RegisterConstant(value + offset);
  10.137 +    return RegisterOrConstant(value + offset);
  10.138  
  10.139    // load indirectly to solve generation ordering problem
  10.140    movptr(tmp, ExternalAddress((address) delayed_value_addr));
  10.141 @@ -7571,7 +7605,7 @@
  10.142    if (offset != 0)
  10.143      addptr(tmp, offset);
  10.144  
  10.145 -  return RegisterConstant(tmp);
  10.146 +  return RegisterOrConstant(tmp);
  10.147  }
  10.148  
  10.149  
    11.1 --- a/src/cpu/x86/vm/assembler_x86.hpp	Wed Apr 01 22:31:26 2009 -0700
    11.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp	Thu Apr 02 17:01:00 2009 -0700
    11.3 @@ -212,7 +212,7 @@
    11.4             "inconsistent address");
    11.5    }
    11.6  
    11.7 -  Address(Register base, RegisterConstant index, ScaleFactor scale = times_1, int disp = 0)
    11.8 +  Address(Register base, RegisterOrConstant index, ScaleFactor scale = times_1, int disp = 0)
    11.9      : _base (base),
   11.10        _index(index.register_or_noreg()),
   11.11        _scale(scale),
   11.12 @@ -256,7 +256,7 @@
   11.13             "inconsistent address");
   11.14    }
   11.15  
   11.16 -  Address(Register base, RegisterConstant index, ScaleFactor scale, ByteSize disp)
   11.17 +  Address(Register base, RegisterOrConstant index, ScaleFactor scale, ByteSize disp)
   11.18      : _base (base),
   11.19        _index(index.register_or_noreg()),
   11.20        _scale(scale),
   11.21 @@ -1068,15 +1068,23 @@
   11.22      LoadLoad   = 1 << 0
   11.23    };
   11.24  
   11.25 -  // Serializes memory.
   11.26 +  // Serializes memory and blows flags
   11.27    void membar(Membar_mask_bits order_constraint) {
   11.28 -    // We only have to handle StoreLoad and LoadLoad
   11.29 -    if (order_constraint & StoreLoad) {
   11.30 -      // MFENCE subsumes LFENCE
   11.31 -      mfence();
   11.32 -    } /* [jk] not needed currently: else if (order_constraint & LoadLoad) {
   11.33 -         lfence();
   11.34 -    } */
   11.35 +    if (os::is_MP()) {
   11.36 +      // We only have to handle StoreLoad
   11.37 +      if (order_constraint & StoreLoad) {
   11.38 +        // All usable chips support "locked" instructions which suffice
   11.39 +        // as barriers, and are much faster than the alternative of
   11.40 +        // using cpuid instruction. We use here a locked add [esp],0.
   11.41 +        // This is conveniently otherwise a no-op except for blowing
   11.42 +        // flags.
   11.43 +        // Any change to this code may need to revisit other places in
   11.44 +        // the code where this idiom is used, in particular the
   11.45 +        // orderAccess code.
   11.46 +        lock();
   11.47 +        addl(Address(rsp, 0), 0);// Assert the lock# signal here
   11.48 +      }
   11.49 +    }
   11.50    }
   11.51  
   11.52    void mfence();
   11.53 @@ -1218,6 +1226,10 @@
   11.54    void orq(Register dst, Address src);
   11.55    void orq(Register dst, Register src);
   11.56  
   11.57 +  // SSE4.2 string instructions
   11.58 +  void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
   11.59 +  void pcmpestri(XMMRegister xmm1, Address src, int imm8);
   11.60 +
   11.61    void popl(Address dst);
   11.62  
   11.63  #ifdef _LP64
   11.64 @@ -1252,6 +1264,10 @@
   11.65    // Shift Right Logical Quadword Immediate
   11.66    void psrlq(XMMRegister dst, int shift);
   11.67  
   11.68 +  // Logical Compare Double Quadword
   11.69 +  void ptest(XMMRegister dst, XMMRegister src);
   11.70 +  void ptest(XMMRegister dst, Address src);
   11.71 +
   11.72    // Interleave Low Bytes
   11.73    void punpcklbw(XMMRegister dst, XMMRegister src);
   11.74  
   11.75 @@ -1802,7 +1818,7 @@
   11.76    // interface method calling
   11.77    void lookup_interface_method(Register recv_klass,
   11.78                                 Register intf_klass,
   11.79 -                               RegisterConstant itable_index,
   11.80 +                               RegisterOrConstant itable_index,
   11.81                                 Register method_result,
   11.82                                 Register scan_temp,
   11.83                                 Label& no_such_interface);
   11.84 @@ -1819,7 +1835,7 @@
   11.85                                       Label* L_success,
   11.86                                       Label* L_failure,
   11.87                                       Label* L_slow_path,
   11.88 -                RegisterConstant super_check_offset = RegisterConstant(-1));
   11.89 +                RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
   11.90  
   11.91    // The rest of the type check; must be wired to a corresponding fast path.
   11.92    // It does not repeat the fast path logic, so don't use it standalone.
   11.93 @@ -1883,9 +1899,9 @@
   11.94    // stack overflow + shadow pages.  Also, clobbers tmp
   11.95    void bang_stack_size(Register size, Register tmp);
   11.96  
   11.97 -  virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr,
   11.98 -                                         Register tmp,
   11.99 -                                         int offset);
  11.100 +  virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
  11.101 +                                                Register tmp,
  11.102 +                                                int offset);
  11.103  
  11.104    // Support for serializing memory accesses between threads
  11.105    void serialize_memory(Register thread, Register tmp);
    12.1 --- a/src/cpu/x86/vm/globals_x86.hpp	Wed Apr 01 22:31:26 2009 -0700
    12.2 +++ b/src/cpu/x86/vm/globals_x86.hpp	Thu Apr 02 17:01:00 2009 -0700
    12.3 @@ -60,6 +60,7 @@
    12.4  define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
    12.5  #endif // AMD64
    12.6  define_pd_global(intx,  InlineFrequencyCount,     100);
    12.7 +define_pd_global(intx,  InlineSmallCode,          1000);
    12.8  define_pd_global(intx,  PreInflateSpin,           10);
    12.9  
   12.10  define_pd_global(intx, StackYellowPages, 2);
    13.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Apr 01 22:31:26 2009 -0700
    13.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Apr 02 17:01:00 2009 -0700
    13.3 @@ -2691,7 +2691,7 @@
    13.4    __ mov(rdi, rax);
    13.5  
    13.6     Label noException;
    13.7 -  __ cmpl(r12, Deoptimization::Unpack_exception);   // Was exception pending?
    13.8 +  __ cmpl(r14, Deoptimization::Unpack_exception);   // Was exception pending?
    13.9    __ jcc(Assembler::notEqual, noException);
   13.10    __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset()));
   13.11    // QQQ this is useless it was NULL above
    14.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Apr 01 22:31:26 2009 -0700
    14.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Apr 02 17:01:00 2009 -0700
    14.3 @@ -637,7 +637,7 @@
    14.4    address generate_orderaccess_fence() {
    14.5      StubCodeMark mark(this, "StubRoutines", "orderaccess_fence");
    14.6      address start = __ pc();
    14.7 -    __ mfence();
    14.8 +    __ membar(Assembler::StoreLoad);
    14.9      __ ret(0);
   14.10  
   14.11      return start;
    15.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp	Wed Apr 01 22:31:26 2009 -0700
    15.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp	Thu Apr 02 17:01:00 2009 -0700
    15.3 @@ -408,6 +408,11 @@
    15.4            UseUnalignedLoadStores = true; // use movdqu on newest Intel cpus
    15.5          }
    15.6        }
    15.7 +      if( supports_sse4_2() && UseSSE >= 4 ) {
    15.8 +        if( FLAG_IS_DEFAULT(UseSSE42Intrinsics)) {
    15.9 +          UseSSE42Intrinsics = true;
   15.10 +        }
   15.11 +      }
   15.12      }
   15.13    }
   15.14  
    16.1 --- a/src/cpu/x86/vm/x86_32.ad	Wed Apr 01 22:31:26 2009 -0700
    16.2 +++ b/src/cpu/x86/vm/x86_32.ad	Thu Apr 02 17:01:00 2009 -0700
    16.3 @@ -3694,12 +3694,16 @@
    16.4      }
    16.5    %}
    16.6  
    16.7 -  enc_class enc_String_Compare() %{
    16.8 +  enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
    16.9 +                        eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{
   16.10      Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL,
   16.11            POP_LABEL, DONE_LABEL, CONT_LABEL,
   16.12            WHILE_HEAD_LABEL;
   16.13      MacroAssembler masm(&cbuf);
   16.14  
   16.15 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
   16.16 +    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
   16.17 +
   16.18      // Get the first character position in both strings
   16.19      //         [8] char array, [12] offset, [16] count
   16.20      int value_offset  = java_lang_String::value_offset_in_bytes();
   16.21 @@ -3717,7 +3721,6 @@
   16.22      // Compute the minimum of the string lengths(rsi) and the
   16.23      // difference of the string lengths (stack)
   16.24  
   16.25 -
   16.26      if (VM_Version::supports_cmov()) {
   16.27        masm.movl(rdi, Address(rdi, count_offset));
   16.28        masm.movl(rsi, Address(rsi, count_offset));
   16.29 @@ -3731,7 +3734,7 @@
   16.30        masm.movl(rsi, rdi);
   16.31        masm.subl(rdi, rcx);
   16.32        masm.push(rdi);
   16.33 -      masm.jcc(Assembler::lessEqual, ECX_GOOD_LABEL);
   16.34 +      masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);
   16.35        masm.movl(rsi, rcx);
   16.36        // rsi holds min, rcx is unused
   16.37      }
   16.38 @@ -3756,7 +3759,7 @@
   16.39        Label LSkip2;
   16.40        // Check if the strings start at same location
   16.41        masm.cmpptr(rbx,rax);
   16.42 -      masm.jcc(Assembler::notEqual, LSkip2);
   16.43 +      masm.jccb(Assembler::notEqual, LSkip2);
   16.44  
   16.45        // Check if the length difference is zero (from stack)
   16.46        masm.cmpl(Address(rsp, 0), 0x0);
   16.47 @@ -3766,9 +3769,52 @@
   16.48        masm.bind(LSkip2);
   16.49      }
   16.50  
   16.51 -    // Shift rax, and rbx, to the end of the arrays, negate min
   16.52 -    masm.lea(rax, Address(rax, rsi, Address::times_2, 2));
   16.53 -    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2));
   16.54 +   // Advance to next character
   16.55 +    masm.addptr(rax, 2);
   16.56 +    masm.addptr(rbx, 2);
   16.57 +
   16.58 +    if (UseSSE42Intrinsics) {
   16.59 +      // With SSE4.2, use double quad vector compare
   16.60 +      Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
   16.61 +      // Setup to compare 16-byte vectors
   16.62 +      masm.movl(rdi, rsi);
   16.63 +      masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
   16.64 +      masm.andl(rdi, 0x00000007); // rdi holds the tail count
   16.65 +      masm.testl(rsi, rsi);
   16.66 +      masm.jccb(Assembler::zero, COMPARE_TAIL);
   16.67 +
   16.68 +      masm.lea(rax, Address(rax, rsi, Address::times_2));
   16.69 +      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
   16.70 +      masm.negl(rsi);
   16.71 +
   16.72 +      masm.bind(COMPARE_VECTORS);
   16.73 +      masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
   16.74 +      masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
   16.75 +      masm.pxor(tmp1Reg, tmp2Reg);
   16.76 +      masm.ptest(tmp1Reg, tmp1Reg);
   16.77 +      masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
   16.78 +      masm.addl(rsi, 8);
   16.79 +      masm.jcc(Assembler::notZero, COMPARE_VECTORS);
   16.80 +      masm.jmpb(COMPARE_TAIL);
   16.81 +
   16.82 +      // Mismatched characters in the vectors
   16.83 +      masm.bind(VECTOR_NOT_EQUAL);
   16.84 +      masm.lea(rax, Address(rax, rsi, Address::times_2));
   16.85 +      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
   16.86 +      masm.movl(rdi, 8);
   16.87 +
   16.88 +      // Compare tail (< 8 chars), or rescan last vectors to
   16.89 +      // find 1st mismatched characters
   16.90 +      masm.bind(COMPARE_TAIL);
   16.91 +      masm.testl(rdi, rdi);
   16.92 +      masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
   16.93 +      masm.movl(rsi, rdi);
   16.94 +      // Fallthru to tail compare
   16.95 +    }
   16.96 +
   16.97 +    //Shift rax, and rbx, to the end of the arrays, negate min
   16.98 +    masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
   16.99 +    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
  16.100      masm.negl(rsi);
  16.101  
  16.102      // Compare the rest of the characters
  16.103 @@ -3776,93 +3822,329 @@
  16.104      masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
  16.105      masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
  16.106      masm.subl(rcx, rdi);
  16.107 -    masm.jcc(Assembler::notZero, POP_LABEL);
  16.108 +    masm.jccb(Assembler::notZero, POP_LABEL);
  16.109      masm.incrementl(rsi);
  16.110      masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
  16.111  
  16.112      // Strings are equal up to min length.  Return the length difference.
  16.113      masm.bind(LENGTH_DIFF_LABEL);
  16.114      masm.pop(rcx);
  16.115 -    masm.jmp(DONE_LABEL);
  16.116 +    masm.jmpb(DONE_LABEL);
  16.117  
  16.118      // Discard the stored length difference
  16.119      masm.bind(POP_LABEL);
  16.120      masm.addptr(rsp, 4);
  16.121 -       
  16.122 +
  16.123      // That's it
  16.124      masm.bind(DONE_LABEL);
  16.125    %}
  16.126  
  16.127 -  enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result) %{
  16.128 -    Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
  16.129 + enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
  16.130 +                       eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{
  16.131 +    Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  16.132      MacroAssembler masm(&cbuf);
  16.133  
  16.134 -    Register ary1Reg   = as_Register($ary1$$reg);
  16.135 -    Register ary2Reg   = as_Register($ary2$$reg);
  16.136 -    Register tmp1Reg   = as_Register($tmp1$$reg);
  16.137 -    Register tmp2Reg   = as_Register($tmp2$$reg);
  16.138 -    Register resultReg = as_Register($result$$reg);
  16.139 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  16.140 +    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  16.141 +
  16.142 +    int value_offset  = java_lang_String::value_offset_in_bytes();
  16.143 +    int offset_offset = java_lang_String::offset_offset_in_bytes();
  16.144 +    int count_offset  = java_lang_String::count_offset_in_bytes();
  16.145 +    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  16.146 +
  16.147 +    // does source == target string?
  16.148 +    masm.cmpptr(rdi, rsi);
  16.149 +    masm.jcc(Assembler::equal, RET_TRUE);
  16.150 +
  16.151 +    // get and compare counts
  16.152 +    masm.movl(rcx, Address(rdi, count_offset));
  16.153 +    masm.movl(rax, Address(rsi, count_offset));
  16.154 +    masm.cmpl(rcx, rax);
  16.155 +    masm.jcc(Assembler::notEqual, RET_FALSE);
  16.156 +    masm.testl(rax, rax);
  16.157 +    masm.jcc(Assembler::zero, RET_TRUE);
  16.158 +
  16.159 +    // get source string offset and value
  16.160 +    masm.movptr(rbx, Address(rsi, value_offset));
  16.161 +    masm.movl(rax, Address(rsi, offset_offset));
  16.162 +    masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));
  16.163 +
  16.164 +    // get compare string offset and value
  16.165 +    masm.movptr(rbx, Address(rdi, value_offset));
  16.166 +    masm.movl(rax, Address(rdi, offset_offset));
  16.167 +    masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));
  16.168 +
  16.169 +    // Set byte count
  16.170 +    masm.shll(rcx, 1);
  16.171 +    masm.movl(rax, rcx);
  16.172 +
  16.173 +    if (UseSSE42Intrinsics) {
  16.174 +      // With SSE4.2, use double quad vector compare
  16.175 +      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  16.176 +      // Compare 16-byte vectors
  16.177 +      masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
  16.178 +      masm.andl(rax, 0x0000000e);  // tail count (in bytes)
  16.179 +      masm.testl(rcx, rcx);
  16.180 +      masm.jccb(Assembler::zero, COMPARE_TAIL);
  16.181 +      masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  16.182 +      masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  16.183 +      masm.negl(rcx);
  16.184 +
  16.185 +      masm.bind(COMPARE_WIDE_VECTORS);
  16.186 +      masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
  16.187 +      masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
  16.188 +      masm.pxor(tmp1Reg, tmp2Reg);
  16.189 +      masm.ptest(tmp1Reg, tmp1Reg);
  16.190 +      masm.jccb(Assembler::notZero, RET_FALSE);
  16.191 +      masm.addl(rcx, 16);
  16.192 +      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  16.193 +      masm.bind(COMPARE_TAIL);
  16.194 +      masm.movl(rcx, rax);
  16.195 +      // Fallthru to tail compare
  16.196 +    }
  16.197 +
  16.198 +    // Compare 4-byte vectors
  16.199 +    masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
  16.200 +    masm.andl(rax, 0x00000002);  // tail char (in bytes)
  16.201 +    masm.testl(rcx, rcx);
  16.202 +    masm.jccb(Assembler::zero, COMPARE_CHAR);
  16.203 +    masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  16.204 +    masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  16.205 +    masm.negl(rcx);
  16.206 +
  16.207 +    masm.bind(COMPARE_VECTORS);
  16.208 +    masm.movl(rbx, Address(rdi, rcx, Address::times_1));
  16.209 +    masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
  16.210 +    masm.jccb(Assembler::notEqual, RET_FALSE);
  16.211 +    masm.addl(rcx, 4);
  16.212 +    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  16.213 +
  16.214 +    // Compare trailing char (final 2 bytes), if any
  16.215 +    masm.bind(COMPARE_CHAR);
  16.216 +    masm.testl(rax, rax);
  16.217 +    masm.jccb(Assembler::zero, RET_TRUE);
  16.218 +    masm.load_unsigned_short(rbx, Address(rdi, 0));
  16.219 +    masm.load_unsigned_short(rcx, Address(rsi, 0));
  16.220 +    masm.cmpl(rbx, rcx);
  16.221 +    masm.jccb(Assembler::notEqual, RET_FALSE);
  16.222 +
  16.223 +    masm.bind(RET_TRUE);
  16.224 +    masm.movl(rax, 1);   // return true
  16.225 +    masm.jmpb(DONE);
  16.226 +
  16.227 +    masm.bind(RET_FALSE);
  16.228 +    masm.xorl(rax, rax); // return false
  16.229 +
  16.230 +    masm.bind(DONE);
  16.231 +    %}
  16.232 +
  16.233 + enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
  16.234 +                        eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{
  16.235 +    // SSE4.2 version
  16.236 +    Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
  16.237 +          SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
  16.238 +    MacroAssembler masm(&cbuf);
  16.239 +
  16.240 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  16.241 +
  16.242 +    // Get the first character position in both strings
  16.243 +    //         [8] char array, [12] offset, [16] count
  16.244 +    int value_offset  = java_lang_String::value_offset_in_bytes();
  16.245 +    int offset_offset = java_lang_String::offset_offset_in_bytes();
  16.246 +    int count_offset  = java_lang_String::count_offset_in_bytes();
  16.247 +    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  16.248 +
  16.249 +    // Get counts for string and substr
  16.250 +    masm.movl(rdx, Address(rsi, count_offset));
  16.251 +    masm.movl(rax, Address(rdi, count_offset));
  16.252 +    // Check for substr count > string count
  16.253 +    masm.cmpl(rax, rdx);
  16.254 +    masm.jcc(Assembler::greater, RET_NEG_ONE);
  16.255 +
  16.256 +    // Start the indexOf operation
  16.257 +    // Get start addr of string
  16.258 +    masm.movptr(rbx, Address(rsi, value_offset));
  16.259 +    masm.movl(rcx, Address(rsi, offset_offset));
  16.260 +    masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
  16.261 +    masm.push(rsi);
  16.262 +
  16.263 +    // Get start addr of substr
  16.264 +    masm.movptr(rbx, Address(rdi, value_offset));
  16.265 +    masm.movl(rcx, Address(rdi, offset_offset));
  16.266 +    masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
  16.267 +    masm.push(rdi);
  16.268 +    masm.push(rax);
  16.269 +    masm.jmpb(PREP_FOR_SCAN);
  16.270 +
  16.271 +    // Substr count saved at sp
  16.272 +    // Substr saved at sp+4
  16.273 +    // String saved at sp+8
  16.274 +
  16.275 +    // Prep to load substr for scan
  16.276 +    masm.bind(LOAD_SUBSTR);
  16.277 +    masm.movptr(rdi, Address(rsp, 4));
  16.278 +    masm.movl(rax, Address(rsp, 0));
  16.279 +
  16.280 +    // Load substr
  16.281 +    masm.bind(PREP_FOR_SCAN);
  16.282 +    masm.movdqu(tmp1Reg, Address(rdi, 0));
  16.283 +    masm.addl(rdx, 8);        // prime the loop
  16.284 +    masm.subptr(rsi, 16);
  16.285 +
  16.286 +    // Scan string for substr in 16-byte vectors
  16.287 +    masm.bind(SCAN_TO_SUBSTR);
  16.288 +    masm.subl(rdx, 8);
  16.289 +    masm.addptr(rsi, 16);
  16.290 +    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  16.291 +    masm.jcc(Assembler::above, SCAN_TO_SUBSTR);     // CF == 0 && ZF == 0
  16.292 +    masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
  16.293 +
  16.294 +    // Fallthru: found a potential substr
  16.295 +
  16.296 +    // Make sure string is still long enough
  16.297 +    masm.subl(rdx, rcx);
  16.298 +    masm.cmpl(rdx, rax);
  16.299 +    masm.jccb(Assembler::negative, RET_NOT_FOUND);
  16.300 +    // Compute start addr of substr
  16.301 +    masm.lea(rsi, Address(rsi, rcx, Address::times_2));
  16.302 +    masm.movptr(rbx, rsi);
  16.303 +
  16.304 +    // Compare potential substr
  16.305 +    masm.addl(rdx, 8);        // prime the loop
  16.306 +    masm.addl(rax, 8);
  16.307 +    masm.subptr(rsi, 16);
  16.308 +    masm.subptr(rdi, 16);
  16.309 +
  16.310 +    // Scan 16-byte vectors of string and substr
  16.311 +    masm.bind(SCAN_SUBSTR);
  16.312 +    masm.subl(rax, 8);
  16.313 +    masm.subl(rdx, 8);
  16.314 +    masm.addptr(rsi, 16);
  16.315 +    masm.addptr(rdi, 16);
  16.316 +    masm.movdqu(tmp1Reg, Address(rdi, 0));
  16.317 +    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  16.318 +    masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
  16.319 +    masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
  16.320 +
  16.321 +    // Compute substr offset
  16.322 +    masm.movptr(rsi, Address(rsp, 8));
  16.323 +    masm.subptr(rbx, rsi);
  16.324 +    masm.shrl(rbx, 1);
  16.325 +    masm.jmpb(CLEANUP);
  16.326 +
  16.327 +    masm.bind(RET_NEG_ONE);
  16.328 +    masm.movl(rbx, -1);
  16.329 +    masm.jmpb(DONE);
  16.330 +
  16.331 +    masm.bind(RET_NOT_FOUND);
  16.332 +    masm.movl(rbx, -1);
  16.333 +
  16.334 +    masm.bind(CLEANUP);
  16.335 +    masm.addptr(rsp, 12);
  16.336 +
  16.337 +    masm.bind(DONE);
  16.338 +  %}
  16.339 +
  16.340 +  enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,
  16.341 +                             eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{
  16.342 +    Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  16.343 +    MacroAssembler masm(&cbuf);
  16.344 +
  16.345 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  16.346 +    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  16.347 +    Register ary1Reg      = as_Register($ary1$$reg);
  16.348 +    Register ary2Reg      = as_Register($ary2$$reg);
  16.349 +    Register tmp3Reg      = as_Register($tmp3$$reg);
  16.350 +    Register tmp4Reg      = as_Register($tmp4$$reg);
  16.351 +    Register resultReg    = as_Register($result$$reg);
  16.352  
  16.353      int length_offset  = arrayOopDesc::length_offset_in_bytes();
  16.354      int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  16.355  
  16.356      // Check the input args
  16.357 -    masm.cmpl(ary1Reg, ary2Reg);
  16.358 +    masm.cmpptr(ary1Reg, ary2Reg);
  16.359      masm.jcc(Assembler::equal, TRUE_LABEL);
  16.360 -    masm.testl(ary1Reg, ary1Reg);
  16.361 +    masm.testptr(ary1Reg, ary1Reg);
  16.362      masm.jcc(Assembler::zero, FALSE_LABEL);
  16.363 -    masm.testl(ary2Reg, ary2Reg);
  16.364 +    masm.testptr(ary2Reg, ary2Reg);
  16.365      masm.jcc(Assembler::zero, FALSE_LABEL);
  16.366  
  16.367      // Check the lengths
  16.368 -    masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
  16.369 +    masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
  16.370      masm.movl(resultReg, Address(ary2Reg, length_offset));
  16.371 -    masm.cmpl(tmp2Reg, resultReg);
  16.372 +    masm.cmpl(tmp4Reg, resultReg);
  16.373      masm.jcc(Assembler::notEqual, FALSE_LABEL);
  16.374      masm.testl(resultReg, resultReg);
  16.375      masm.jcc(Assembler::zero, TRUE_LABEL);
  16.376  
  16.377 -    // Get the number of 4 byte vectors to compare
  16.378 -    masm.shrl(resultReg, 1);
  16.379 -
  16.380 -    // Check for odd-length arrays
  16.381 -    masm.andl(tmp2Reg, 1);
  16.382 -    masm.testl(tmp2Reg, tmp2Reg);
  16.383 -    masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
  16.384 -
  16.385 -    // Compare 2-byte "tail" at end of arrays
  16.386 -    masm.load_unsigned_short(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
  16.387 -    masm.load_unsigned_short(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
  16.388 -    masm.cmpl(tmp1Reg, tmp2Reg);
  16.389 -    masm.jcc(Assembler::notEqual, FALSE_LABEL);
  16.390 +    // Load array addrs
  16.391 +    masm.lea(ary1Reg, Address(ary1Reg, base_offset));
  16.392 +    masm.lea(ary2Reg, Address(ary2Reg, base_offset));
  16.393 +
  16.394 +    // Set byte count
  16.395 +    masm.shll(tmp4Reg, 1);
  16.396 +    masm.movl(resultReg, tmp4Reg);
  16.397 +
  16.398 +    if (UseSSE42Intrinsics) {
  16.399 +      // With SSE4.2, use double quad vector compare
  16.400 +      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  16.401 +      // Compare 16-byte vectors
  16.402 +      masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
  16.403 +      masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
  16.404 +      masm.testl(tmp4Reg, tmp4Reg);
  16.405 +      masm.jccb(Assembler::zero, COMPARE_TAIL);
  16.406 +      masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  16.407 +      masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  16.408 +      masm.negl(tmp4Reg);
  16.409 +
  16.410 +      masm.bind(COMPARE_WIDE_VECTORS);
  16.411 +      masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  16.412 +      masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  16.413 +      masm.pxor(tmp1Reg, tmp2Reg);
  16.414 +      masm.ptest(tmp1Reg, tmp1Reg);
  16.415 +
  16.416 +      masm.jccb(Assembler::notZero, FALSE_LABEL);
  16.417 +      masm.addl(tmp4Reg, 16);
  16.418 +      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  16.419 +      masm.bind(COMPARE_TAIL);
  16.420 +      masm.movl(tmp4Reg, resultReg);
  16.421 +      // Fallthru to tail compare
  16.422 +    }
  16.423 +
  16.424 +    // Compare 4-byte vectors
  16.425 +    masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
  16.426 +    masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
  16.427 +    masm.testl(tmp4Reg, tmp4Reg);
  16.428 +    masm.jccb(Assembler::zero, COMPARE_CHAR);
  16.429 +    masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  16.430 +    masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  16.431 +    masm.negl(tmp4Reg);
  16.432 +
  16.433 +    masm.bind(COMPARE_VECTORS);
  16.434 +    masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  16.435 +    masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  16.436 +    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  16.437 +    masm.addl(tmp4Reg, 4);
  16.438 +    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  16.439 +
  16.440 +    // Compare trailing char (final 2 bytes), if any
  16.441 +    masm.bind(COMPARE_CHAR);
  16.442      masm.testl(resultReg, resultReg);
  16.443 -    masm.jcc(Assembler::zero, TRUE_LABEL);
  16.444 -
  16.445 -    // Setup compare loop
  16.446 -    masm.bind(COMPARE_LOOP_HDR);
  16.447 -    // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
  16.448 -    masm.leal(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
  16.449 -    masm.leal(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
  16.450 -    masm.negl(resultReg);
  16.451 -
  16.452 -    // 4-byte-wide compare loop
  16.453 -    masm.bind(COMPARE_LOOP);
  16.454 -    masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
  16.455 -    masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
  16.456 -    masm.cmpl(ary1Reg, ary2Reg);
  16.457 -    masm.jcc(Assembler::notEqual, FALSE_LABEL);
  16.458 -    masm.increment(resultReg);
  16.459 -    masm.jcc(Assembler::notZero, COMPARE_LOOP);
  16.460 +    masm.jccb(Assembler::zero, TRUE_LABEL);
  16.461 +    masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
  16.462 +    masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
  16.463 +    masm.cmpl(tmp3Reg, tmp4Reg);
  16.464 +    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  16.465  
  16.466      masm.bind(TRUE_LABEL);
  16.467      masm.movl(resultReg, 1);   // return true
  16.468 -    masm.jmp(DONE_LABEL);
  16.469 +    masm.jmpb(DONE);
  16.470  
  16.471      masm.bind(FALSE_LABEL);
  16.472      masm.xorl(resultReg, resultReg); // return false
  16.473  
  16.474      // That's it
  16.475 -    masm.bind(DONE_LABEL);
  16.476 +    masm.bind(DONE);
  16.477    %}
  16.478  
  16.479    enc_class enc_pop_rdx() %{
  16.480 @@ -4288,24 +4570,6 @@
  16.481      emit_opcode(cbuf, 0xC8 + $src2$$reg);
  16.482    %}
  16.483  
  16.484 -  enc_class enc_membar_acquire %{
  16.485 -    // Doug Lea believes this is not needed with current Sparcs and TSO.
  16.486 -    // MacroAssembler masm(&cbuf);
  16.487 -    // masm.membar();
  16.488 -  %}
  16.489 -
  16.490 -  enc_class enc_membar_release %{
  16.491 -    // Doug Lea believes this is not needed with current Sparcs and TSO.
  16.492 -    // MacroAssembler masm(&cbuf);
  16.493 -    // masm.membar();
  16.494 -  %}
  16.495 -
  16.496 -  enc_class enc_membar_volatile %{
  16.497 -    MacroAssembler masm(&cbuf);
  16.498 -    masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad |
  16.499 -                                            Assembler::StoreStore));
  16.500 -  %}
  16.501 -
  16.502    // Atomically load the volatile long
  16.503    enc_class enc_loadL_volatile( memory mem, stackSlotL dst ) %{
  16.504      emit_opcode(cbuf,0xDF);
  16.505 @@ -7498,9 +7762,9 @@
  16.506    ins_cost(400);
  16.507  
  16.508    size(0);
  16.509 -  format %{ "MEMBAR-acquire" %}
  16.510 -  ins_encode( enc_membar_acquire );
  16.511 -  ins_pipe(pipe_slow);
  16.512 +  format %{ "MEMBAR-acquire ! (empty encoding)" %}
  16.513 +  ins_encode();
  16.514 +  ins_pipe(empty);
  16.515  %}
  16.516  
  16.517  instruct membar_acquire_lock() %{
  16.518 @@ -7519,9 +7783,9 @@
  16.519    ins_cost(400);
  16.520  
  16.521    size(0);
  16.522 -  format %{ "MEMBAR-release" %}
  16.523 -  ins_encode( enc_membar_release );
  16.524 -  ins_pipe(pipe_slow);
  16.525 +  format %{ "MEMBAR-release ! (empty encoding)" %}
  16.526 +  ins_encode( );
  16.527 +  ins_pipe(empty);
  16.528  %}
  16.529  
  16.530  instruct membar_release_lock() %{
  16.531 @@ -7535,12 +7799,22 @@
  16.532    ins_pipe(empty);
  16.533  %}
  16.534  
  16.535 -instruct membar_volatile() %{
  16.536 +instruct membar_volatile(eFlagsReg cr) %{
  16.537    match(MemBarVolatile);
  16.538 +  effect(KILL cr);
  16.539    ins_cost(400);
  16.540  
  16.541 -  format %{ "MEMBAR-volatile" %}
  16.542 -  ins_encode( enc_membar_volatile );
  16.543 +  format %{ 
  16.544 +    $$template
  16.545 +    if (os::is_MP()) {
  16.546 +      $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile"
  16.547 +    } else {
  16.548 +      $$emit$$"MEMBAR-volatile ! (empty encoding)"
  16.549 +    }
  16.550 +  %}
  16.551 +  ins_encode %{
  16.552 +    __ membar(Assembler::StoreLoad);
  16.553 +  %}
  16.554    ins_pipe(pipe_slow);
  16.555  %}
  16.556  
  16.557 @@ -12082,11 +12356,8 @@
  16.558    ins_pipe( fpu_reg_reg );
  16.559  %}
  16.560  
  16.561 -
  16.562 -
  16.563  // =======================================================================
  16.564  // fast clearing of an array
  16.565 -
  16.566  instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
  16.567    match(Set dummy (ClearArray cnt base));
  16.568    effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
  16.569 @@ -12100,24 +12371,48 @@
  16.570    ins_pipe( pipe_slow );
  16.571  %}
  16.572  
  16.573 -instruct string_compare(eDIRegP str1, eSIRegP str2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{
  16.574 +instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
  16.575 +                        eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{
  16.576    match(Set result (StrComp str1 str2));
  16.577 -  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr);
  16.578 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  16.579    //ins_cost(300);
  16.580  
  16.581    format %{ "String Compare $str1,$str2 -> $result    // KILL EAX, EBX" %}
  16.582 -  ins_encode( enc_String_Compare() );
  16.583 +  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  16.584 +  ins_pipe( pipe_slow );
  16.585 +%}
  16.586 +
  16.587 +// fast string equals
  16.588 +instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
  16.589 +                       eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
  16.590 +  match(Set result (StrEquals str1 str2));
  16.591 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  16.592 +
  16.593 +  format %{ "String Equals $str1,$str2 -> $result    // KILL EBX, ECX" %}
  16.594 +  ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) );
  16.595 +  ins_pipe( pipe_slow );
  16.596 +%}
  16.597 +
  16.598 +instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
  16.599 +                        eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{
  16.600 +  predicate(UseSSE42Intrinsics);
  16.601 +  match(Set result (StrIndexOf str1 str2));
  16.602 +  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
  16.603 +
  16.604 +  format %{ "String IndexOf $str1,$str2 -> $result    // KILL EAX, ECX, EDX" %}
  16.605 +  ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  16.606    ins_pipe( pipe_slow );
  16.607  %}
  16.608  
  16.609  // fast array equals
  16.610 -instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{
  16.611 +instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3,
  16.612 +                      eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
  16.613    match(Set result (AryEq ary1 ary2));
  16.614 -  effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
  16.615 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
  16.616    //ins_cost(300);
  16.617  
  16.618 -  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL EAX, EBX" %}
  16.619 -  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
  16.620 +  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL EBX, EDX" %}
  16.621 +  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
  16.622    ins_pipe( pipe_slow );
  16.623  %}
  16.624  
    17.1 --- a/src/cpu/x86/vm/x86_64.ad	Wed Apr 01 22:31:26 2009 -0700
    17.2 +++ b/src/cpu/x86/vm/x86_64.ad	Thu Apr 02 17:01:00 2009 -0700
    17.3 @@ -3694,13 +3694,16 @@
    17.4      }
    17.5    %}
    17.6  
    17.7 -  enc_class enc_String_Compare()
    17.8 -  %{
    17.9 +  enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
   17.10 +                        rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
   17.11      Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL,
   17.12            POP_LABEL, DONE_LABEL, CONT_LABEL,
   17.13            WHILE_HEAD_LABEL;
   17.14      MacroAssembler masm(&cbuf);
   17.15  
   17.16 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
   17.17 +    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
   17.18 +
   17.19      // Get the first character position in both strings
   17.20      //         [8] char array, [12] offset, [16] count
   17.21      int value_offset  = java_lang_String::value_offset_in_bytes();
   17.22 @@ -3718,6 +3721,7 @@
   17.23      // Compute the minimum of the string lengths(rsi) and the
   17.24      // difference of the string lengths (stack)
   17.25  
   17.26 +    // do the conditional move stuff
   17.27      masm.movl(rdi, Address(rdi, count_offset));
   17.28      masm.movl(rsi, Address(rsi, count_offset));
   17.29      masm.movl(rcx, rdi);
   17.30 @@ -3745,7 +3749,7 @@
   17.31        Label LSkip2;
   17.32        // Check if the strings start at same location
   17.33        masm.cmpptr(rbx, rax);
   17.34 -      masm.jcc(Assembler::notEqual, LSkip2);
   17.35 +      masm.jccb(Assembler::notEqual, LSkip2);
   17.36  
   17.37        // Check if the length difference is zero (from stack)
   17.38        masm.cmpl(Address(rsp, 0), 0x0);
   17.39 @@ -3755,9 +3759,52 @@
   17.40        masm.bind(LSkip2);
   17.41      }
   17.42  
   17.43 +    // Advance to next character
   17.44 +    masm.addptr(rax, 2);
   17.45 +    masm.addptr(rbx, 2);
   17.46 +
   17.47 +    if (UseSSE42Intrinsics) {
   17.48 +      // With SSE4.2, use double quad vector compare
   17.49 +      Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
   17.50 +      // Setup to compare 16-byte vectors
   17.51 +      masm.movl(rdi, rsi);
   17.52 +      masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
   17.53 +      masm.andl(rdi, 0x00000007); // rdi holds the tail count
   17.54 +      masm.testl(rsi, rsi);
   17.55 +      masm.jccb(Assembler::zero, COMPARE_TAIL);
   17.56 +
   17.57 +      masm.lea(rax, Address(rax, rsi, Address::times_2));
   17.58 +      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
   17.59 +      masm.negptr(rsi);
   17.60 +
   17.61 +      masm.bind(COMPARE_VECTORS);
   17.62 +      masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
   17.63 +      masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
   17.64 +      masm.pxor(tmp1Reg, tmp2Reg);
   17.65 +      masm.ptest(tmp1Reg, tmp1Reg);
   17.66 +      masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
   17.67 +      masm.addptr(rsi, 8);
   17.68 +      masm.jcc(Assembler::notZero, COMPARE_VECTORS);
   17.69 +      masm.jmpb(COMPARE_TAIL);
   17.70 +
   17.71 +      // Mismatched characters in the vectors
   17.72 +      masm.bind(VECTOR_NOT_EQUAL);
   17.73 +      masm.lea(rax, Address(rax, rsi, Address::times_2));
   17.74 +      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
   17.75 +      masm.movl(rdi, 8);
   17.76 +
   17.77 +      // Compare tail (< 8 chars), or rescan last vectors to
   17.78 +      // find 1st mismatched characters
   17.79 +      masm.bind(COMPARE_TAIL);
   17.80 +      masm.testl(rdi, rdi);
   17.81 +      masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
   17.82 +      masm.movl(rsi, rdi);
   17.83 +      // Fallthru to tail compare
   17.84 +    }
   17.85 +
   17.86      // Shift RAX and RBX to the end of the arrays, negate min
   17.87 -    masm.lea(rax, Address(rax, rsi, Address::times_2, 2));
   17.88 -    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2));
   17.89 +    masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
   17.90 +    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
   17.91      masm.negptr(rsi);
   17.92  
   17.93      // Compare the rest of the characters
   17.94 @@ -3765,93 +3812,329 @@
   17.95      masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
   17.96      masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
   17.97      masm.subl(rcx, rdi);
   17.98 -    masm.jcc(Assembler::notZero, POP_LABEL);
   17.99 +    masm.jccb(Assembler::notZero, POP_LABEL);
  17.100      masm.increment(rsi);
  17.101      masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
  17.102  
  17.103      // Strings are equal up to min length.  Return the length difference.
  17.104      masm.bind(LENGTH_DIFF_LABEL);
  17.105      masm.pop(rcx);
  17.106 -    masm.jmp(DONE_LABEL);
  17.107 +    masm.jmpb(DONE_LABEL);
  17.108  
  17.109      // Discard the stored length difference
  17.110      masm.bind(POP_LABEL);
  17.111      masm.addptr(rsp, 8);
  17.112 -       
  17.113 +
  17.114      // That's it
  17.115      masm.bind(DONE_LABEL);
  17.116    %}
  17.117  
  17.118 -  enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{
  17.119 -    Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
  17.120 + enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
  17.121 +                        rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{
  17.122 +    // SSE4.2 version
  17.123 +    Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
  17.124 +          SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
  17.125      MacroAssembler masm(&cbuf);
  17.126  
  17.127 -    Register ary1Reg   = as_Register($ary1$$reg);
  17.128 -    Register ary2Reg   = as_Register($ary2$$reg);
  17.129 -    Register tmp1Reg   = as_Register($tmp1$$reg);
  17.130 -    Register tmp2Reg   = as_Register($tmp2$$reg);
  17.131 -    Register resultReg = as_Register($result$$reg);
  17.132 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  17.133 +
  17.134 +    // Get the first character position in both strings
  17.135 +    //         [8] char array, [12] offset, [16] count
  17.136 +    int value_offset  = java_lang_String::value_offset_in_bytes();
  17.137 +    int offset_offset = java_lang_String::offset_offset_in_bytes();
  17.138 +    int count_offset  = java_lang_String::count_offset_in_bytes();
  17.139 +    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  17.140 +
  17.141 +    // Get counts for string and substr
  17.142 +    masm.movl(rdx, Address(rsi, count_offset));
  17.143 +    masm.movl(rax, Address(rdi, count_offset));
  17.144 +    // Check for substr count > string count
  17.145 +    masm.cmpl(rax, rdx);
  17.146 +    masm.jcc(Assembler::greater, RET_NEG_ONE);
  17.147 +
  17.148 +    // Start the indexOf operation
  17.149 +    // Get start addr of string
  17.150 +    masm.load_heap_oop(rbx, Address(rsi, value_offset));
  17.151 +    masm.movl(rcx, Address(rsi, offset_offset));
  17.152 +    masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
  17.153 +    masm.push(rsi);
  17.154 +
  17.155 +    // Get start addr of substr
  17.156 +    masm.load_heap_oop(rbx, Address(rdi, value_offset));
  17.157 +    masm.movl(rcx, Address(rdi, offset_offset));
  17.158 +    masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
  17.159 +    masm.push(rdi);
  17.160 +    masm.push(rax);
  17.161 +    masm.jmpb(PREP_FOR_SCAN);
  17.162 +
  17.163 +    // Substr count saved at sp
  17.164 +    // Substr saved at sp+8
  17.165 +    // String saved at sp+16
  17.166 +
  17.167 +    // Prep to load substr for scan
  17.168 +    masm.bind(LOAD_SUBSTR);
  17.169 +    masm.movptr(rdi, Address(rsp, 8));
  17.170 +    masm.movl(rax, Address(rsp, 0));
  17.171 +
  17.172 +    // Load substr
  17.173 +    masm.bind(PREP_FOR_SCAN);
  17.174 +    masm.movdqu(tmp1Reg, Address(rdi, 0));
  17.175 +    masm.addq(rdx, 8);    // prime the loop
  17.176 +    masm.subptr(rsi, 16);
  17.177 +
  17.178 +    // Scan string for substr in 16-byte vectors
  17.179 +    masm.bind(SCAN_TO_SUBSTR);
  17.180 +    masm.subq(rdx, 8);
  17.181 +    masm.addptr(rsi, 16);
  17.182 +    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  17.183 +    masm.jcc(Assembler::above, SCAN_TO_SUBSTR);
  17.184 +    masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND);
  17.185 +
  17.186 +    // Fallthru: found a potential substr
  17.187 +
  17.188 +    //Make sure string is still long enough
  17.189 +    masm.subl(rdx, rcx);
  17.190 +    masm.cmpl(rdx, rax);
  17.191 +    masm.jccb(Assembler::negative, RET_NOT_FOUND);
  17.192 +    // Compute start addr of substr
  17.193 +    masm.lea(rsi, Address(rsi, rcx, Address::times_2));
  17.194 +    masm.movptr(rbx, rsi);
  17.195 +
  17.196 +    // Compare potential substr
  17.197 +    masm.addq(rdx, 8);        // prime the loop
  17.198 +    masm.addq(rax, 8);
  17.199 +    masm.subptr(rsi, 16);
  17.200 +    masm.subptr(rdi, 16);
  17.201 +
  17.202 +    // Scan 16-byte vectors of string and substr
  17.203 +    masm.bind(SCAN_SUBSTR);
  17.204 +    masm.subq(rax, 8);
  17.205 +    masm.subq(rdx, 8);
  17.206 +    masm.addptr(rsi, 16);
  17.207 +    masm.addptr(rdi, 16);
  17.208 +    masm.movdqu(tmp1Reg, Address(rdi, 0));
  17.209 +    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
  17.210 +    masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
  17.211 +    masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
  17.212 +
  17.213 +    // Compute substr offset
  17.214 +    masm.movptr(rsi, Address(rsp, 16));
  17.215 +    masm.subptr(rbx, rsi);
  17.216 +    masm.shrl(rbx, 1);
  17.217 +    masm.jmpb(CLEANUP);
  17.218 +
  17.219 +    masm.bind(RET_NEG_ONE);
  17.220 +    masm.movl(rbx, -1);
  17.221 +    masm.jmpb(DONE);
  17.222 +
  17.223 +    masm.bind(RET_NOT_FOUND);
  17.224 +    masm.movl(rbx, -1);
  17.225 +
  17.226 +    masm.bind(CLEANUP);
  17.227 +    masm.addptr(rsp, 24);
  17.228 +
  17.229 +    masm.bind(DONE);
  17.230 +  %}
  17.231 +
  17.232 +  enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
  17.233 +                              rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{
  17.234 +    Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  17.235 +    MacroAssembler masm(&cbuf);
  17.236 +
  17.237 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  17.238 +    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  17.239 +
  17.240 +    int value_offset  = java_lang_String::value_offset_in_bytes();
  17.241 +    int offset_offset = java_lang_String::offset_offset_in_bytes();
  17.242 +    int count_offset  = java_lang_String::count_offset_in_bytes();
  17.243 +    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  17.244 +
  17.245 +    // does source == target string?
  17.246 +    masm.cmpptr(rdi, rsi);
  17.247 +    masm.jcc(Assembler::equal, RET_TRUE);
  17.248 +
  17.249 +    // get and compare counts
  17.250 +    masm.movl(rcx, Address(rdi, count_offset));
  17.251 +    masm.movl(rax, Address(rsi, count_offset));
  17.252 +    masm.cmpl(rcx, rax);
  17.253 +    masm.jcc(Assembler::notEqual, RET_FALSE);
  17.254 +    masm.testl(rax, rax);
  17.255 +    masm.jcc(Assembler::zero, RET_TRUE);
  17.256 +
  17.257 +    // get source string offset and value
  17.258 +    masm.load_heap_oop(rbx, Address(rsi, value_offset));
  17.259 +    masm.movl(rax, Address(rsi, offset_offset));
  17.260 +    masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset));
  17.261 +
  17.262 +    // get compare string offset and value
  17.263 +    masm.load_heap_oop(rbx, Address(rdi, value_offset));
  17.264 +    masm.movl(rax, Address(rdi, offset_offset));
  17.265 +    masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset));
  17.266 +
  17.267 +    // Set byte count
  17.268 +    masm.shll(rcx, 1);
  17.269 +    masm.movl(rax, rcx);
  17.270 +
  17.271 +    if (UseSSE42Intrinsics) {
  17.272 +      // With SSE4.2, use double quad vector compare
  17.273 +      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  17.274 +      // Compare 16-byte vectors
  17.275 +      masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
  17.276 +      masm.andl(rax, 0x0000000e);  // tail count (in bytes)
  17.277 +      masm.testl(rcx, rcx);
  17.278 +      masm.jccb(Assembler::zero, COMPARE_TAIL);
  17.279 +      masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  17.280 +      masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  17.281 +      masm.negptr(rcx);
  17.282 +
  17.283 +      masm.bind(COMPARE_WIDE_VECTORS);
  17.284 +      masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
  17.285 +      masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
  17.286 +      masm.pxor(tmp1Reg, tmp2Reg);
  17.287 +      masm.ptest(tmp1Reg, tmp1Reg);
  17.288 +      masm.jccb(Assembler::notZero, RET_FALSE);
  17.289 +      masm.addptr(rcx, 16);
  17.290 +      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  17.291 +      masm.bind(COMPARE_TAIL);
  17.292 +      masm.movl(rcx, rax);
  17.293 +      // Fallthru to tail compare
  17.294 +    }
  17.295 +
  17.296 +    // Compare 4-byte vectors
  17.297 +    masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
  17.298 +    masm.andl(rax, 0x00000002);  // tail char (in bytes)
  17.299 +    masm.testl(rcx, rcx);
  17.300 +    masm.jccb(Assembler::zero, COMPARE_CHAR);
  17.301 +    masm.lea(rdi, Address(rdi, rcx, Address::times_1));
  17.302 +    masm.lea(rsi, Address(rsi, rcx, Address::times_1));
  17.303 +    masm.negptr(rcx);
  17.304 +
  17.305 +    masm.bind(COMPARE_VECTORS);
  17.306 +    masm.movl(rbx, Address(rdi, rcx, Address::times_1));
  17.307 +    masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
  17.308 +    masm.jccb(Assembler::notEqual, RET_FALSE);
  17.309 +    masm.addptr(rcx, 4);
  17.310 +    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  17.311 +
  17.312 +    // Compare trailing char (final 2 bytes), if any
  17.313 +    masm.bind(COMPARE_CHAR);
  17.314 +    masm.testl(rax, rax);
  17.315 +    masm.jccb(Assembler::zero, RET_TRUE);
  17.316 +    masm.load_unsigned_short(rbx, Address(rdi, 0));
  17.317 +    masm.load_unsigned_short(rcx, Address(rsi, 0));
  17.318 +    masm.cmpl(rbx, rcx);
  17.319 +    masm.jccb(Assembler::notEqual, RET_FALSE);
  17.320 +
  17.321 +    masm.bind(RET_TRUE);
  17.322 +    masm.movl(rax, 1);   // return true
  17.323 +    masm.jmpb(DONE);
  17.324 +
  17.325 +    masm.bind(RET_FALSE);
  17.326 +    masm.xorl(rax, rax); // return false
  17.327 +
  17.328 +    masm.bind(DONE);
  17.329 +  %}
  17.330 +
  17.331 +  enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2,
  17.332 +                             rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
  17.333 +    Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
  17.334 +    MacroAssembler masm(&cbuf);
  17.335 +
  17.336 +    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
  17.337 +    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
  17.338 +    Register ary1Reg      = as_Register($ary1$$reg);
  17.339 +    Register ary2Reg      = as_Register($ary2$$reg);
  17.340 +    Register tmp3Reg      = as_Register($tmp3$$reg);
  17.341 +    Register tmp4Reg      = as_Register($tmp4$$reg);
  17.342 +    Register resultReg    = as_Register($result$$reg);
  17.343  
  17.344      int length_offset  = arrayOopDesc::length_offset_in_bytes();
  17.345      int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
  17.346  
  17.347      // Check the input args
  17.348 -    masm.cmpq(ary1Reg, ary2Reg);                        
  17.349 +    masm.cmpq(ary1Reg, ary2Reg);
  17.350      masm.jcc(Assembler::equal, TRUE_LABEL);
  17.351 -    masm.testq(ary1Reg, ary1Reg);                       
  17.352 +    masm.testq(ary1Reg, ary1Reg);
  17.353      masm.jcc(Assembler::zero, FALSE_LABEL);
  17.354 -    masm.testq(ary2Reg, ary2Reg);                       
  17.355 +    masm.testq(ary2Reg, ary2Reg);
  17.356      masm.jcc(Assembler::zero, FALSE_LABEL);
  17.357  
  17.358      // Check the lengths
  17.359 -    masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
  17.360 +    masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
  17.361      masm.movl(resultReg, Address(ary2Reg, length_offset));
  17.362 -    masm.cmpl(tmp2Reg, resultReg);
  17.363 +    masm.cmpl(tmp4Reg, resultReg);
  17.364      masm.jcc(Assembler::notEqual, FALSE_LABEL);
  17.365      masm.testl(resultReg, resultReg);
  17.366      masm.jcc(Assembler::zero, TRUE_LABEL);
  17.367  
  17.368 -    // Get the number of 4 byte vectors to compare
  17.369 -    masm.shrl(resultReg, 1);
  17.370 -
  17.371 -    // Check for odd-length arrays
  17.372 -    masm.andl(tmp2Reg, 1);
  17.373 -    masm.testl(tmp2Reg, tmp2Reg);
  17.374 -    masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
  17.375 -
  17.376 -    // Compare 2-byte "tail" at end of arrays
  17.377 -    masm.load_unsigned_short(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
  17.378 -    masm.load_unsigned_short(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
  17.379 -    masm.cmpl(tmp1Reg, tmp2Reg);
  17.380 -    masm.jcc(Assembler::notEqual, FALSE_LABEL);
  17.381 +    //load array address
  17.382 +    masm.lea(ary1Reg, Address(ary1Reg, base_offset));
  17.383 +    masm.lea(ary2Reg, Address(ary2Reg, base_offset));
  17.384 +
  17.385 +    //set byte count
  17.386 +    masm.shll(tmp4Reg, 1);
  17.387 +    masm.movl(resultReg,tmp4Reg);
  17.388 +
  17.389 +    if (UseSSE42Intrinsics){
  17.390 +      // With SSE4.2, use double quad vector compare
  17.391 +      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
  17.392 +      // Compare 16-byte vectors
  17.393 +      masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
  17.394 +      masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
  17.395 +      masm.testl(tmp4Reg, tmp4Reg);
  17.396 +      masm.jccb(Assembler::zero, COMPARE_TAIL);
  17.397 +      masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  17.398 +      masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  17.399 +      masm.negptr(tmp4Reg);
  17.400 +
  17.401 +      masm.bind(COMPARE_WIDE_VECTORS);
  17.402 +      masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  17.403 +      masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  17.404 +      masm.pxor(tmp1Reg, tmp2Reg);
  17.405 +      masm.ptest(tmp1Reg, tmp1Reg);
  17.406 +
  17.407 +      masm.jccb(Assembler::notZero, FALSE_LABEL);
  17.408 +      masm.addptr(tmp4Reg, 16);
  17.409 +      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
  17.410 +      masm.bind(COMPARE_TAIL);
  17.411 +      masm.movl(tmp4Reg, resultReg);
  17.412 +      // Fallthru to tail compare
  17.413 +    }
  17.414 +
  17.415 +   // Compare 4-byte vectors
  17.416 +    masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
  17.417 +    masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
  17.418 +    masm.testl(tmp4Reg, tmp4Reg); //if tmp2 == 0, only compare char
  17.419 +    masm.jccb(Assembler::zero, COMPARE_CHAR);
  17.420 +    masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  17.421 +    masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  17.422 +    masm.negptr(tmp4Reg);
  17.423 +
  17.424 +    masm.bind(COMPARE_VECTORS);
  17.425 +    masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
  17.426 +    masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
  17.427 +    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  17.428 +    masm.addptr(tmp4Reg, 4);
  17.429 +    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
  17.430 +
  17.431 +    // Compare trailing char (final 2 bytes), if any
  17.432 +    masm.bind(COMPARE_CHAR);
  17.433      masm.testl(resultReg, resultReg);
  17.434 -    masm.jcc(Assembler::zero, TRUE_LABEL);
  17.435 -
  17.436 -    // Setup compare loop
  17.437 -    masm.bind(COMPARE_LOOP_HDR);
  17.438 -    // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
  17.439 -    masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
  17.440 -    masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
  17.441 -    masm.negq(resultReg);
  17.442 -
  17.443 -    // 4-byte-wide compare loop
  17.444 -    masm.bind(COMPARE_LOOP);
  17.445 -    masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
  17.446 -    masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
  17.447 -    masm.cmpl(ary1Reg, ary2Reg);
  17.448 -    masm.jcc(Assembler::notEqual, FALSE_LABEL);
  17.449 -    masm.incrementq(resultReg);
  17.450 -    masm.jcc(Assembler::notZero, COMPARE_LOOP);
  17.451 +    masm.jccb(Assembler::zero, TRUE_LABEL);
  17.452 +    masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
  17.453 +    masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
  17.454 +    masm.cmpl(tmp3Reg, tmp4Reg);
  17.455 +    masm.jccb(Assembler::notEqual, FALSE_LABEL);
  17.456  
  17.457      masm.bind(TRUE_LABEL);
  17.458      masm.movl(resultReg, 1);   // return true
  17.459 -    masm.jmp(DONE_LABEL);
  17.460 +    masm.jmpb(DONE);
  17.461  
  17.462      masm.bind(FALSE_LABEL);
  17.463      masm.xorl(resultReg, resultReg); // return false
  17.464  
  17.465      // That's it
  17.466 -    masm.bind(DONE_LABEL);
  17.467 +    masm.bind(DONE);
  17.468    %}
  17.469  
  17.470    enc_class enc_rethrow()
  17.471 @@ -4162,33 +4445,6 @@
  17.472      // done:
  17.473    %}
  17.474  
  17.475 -  enc_class enc_membar_acquire
  17.476 -  %{
  17.477 -    // [jk] not needed currently, if you enable this and it really
  17.478 -    // emits code don't forget to the remove the "size(0)" line in
  17.479 -    // membar_acquire()
  17.480 -    // MacroAssembler masm(&cbuf);
  17.481 -    // masm.membar(Assembler::Membar_mask_bits(Assembler::LoadStore |
  17.482 -    //                                         Assembler::LoadLoad));
  17.483 -  %}
  17.484 -
  17.485 -  enc_class enc_membar_release
  17.486 -  %{
  17.487 -    // [jk] not needed currently, if you enable this and it really
  17.488 -    // emits code don't forget to the remove the "size(0)" line in
  17.489 -    // membar_release()
  17.490 -    // MacroAssembler masm(&cbuf);
  17.491 -    // masm.membar(Assembler::Membar_mask_bits(Assembler::LoadStore |
  17.492 -    //                                         Assembler::StoreStore));
  17.493 -  %}
  17.494 -
  17.495 -  enc_class enc_membar_volatile
  17.496 -  %{
  17.497 -    MacroAssembler masm(&cbuf);
  17.498 -    masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad |
  17.499 -                                            Assembler::StoreStore));
  17.500 -  %}
  17.501 -
  17.502    // Safepoint Poll.  This polls the safepoint page, and causes an
  17.503    // exception if it is not readable. Unfortunately, it kills
  17.504    // RFLAGS in the process.
  17.505 @@ -5114,7 +5370,7 @@
  17.506  %}
  17.507  
  17.508  // Double register operands
  17.509 -operand regD()
  17.510 +operand regD() 
  17.511  %{
  17.512    constraint(ALLOC_IN_RC(double_reg));
  17.513    match(RegD);
  17.514 @@ -7458,7 +7714,7 @@
  17.515    ins_cost(0);
  17.516  
  17.517    size(0);
  17.518 -  format %{ "MEMBAR-acquire" %}
  17.519 +  format %{ "MEMBAR-acquire ! (empty encoding)" %}
  17.520    ins_encode();
  17.521    ins_pipe(empty);
  17.522  %}
  17.523 @@ -7481,7 +7737,7 @@
  17.524    ins_cost(0);
  17.525  
  17.526    size(0);
  17.527 -  format %{ "MEMBAR-release" %}
  17.528 +  format %{ "MEMBAR-release ! (empty encoding)" %}
  17.529    ins_encode();
  17.530    ins_pipe(empty);
  17.531  %}
  17.532 @@ -7498,13 +7754,22 @@
  17.533    ins_pipe(empty);
  17.534  %}
  17.535  
  17.536 -instruct membar_volatile()
  17.537 -%{
  17.538 +instruct membar_volatile(rFlagsReg cr) %{
  17.539    match(MemBarVolatile);
  17.540 +  effect(KILL cr);
  17.541    ins_cost(400);
  17.542  
  17.543 -  format %{ "MEMBAR-volatile" %}
  17.544 -  ins_encode(enc_membar_volatile);
  17.545 +  format %{ 
  17.546 +    $$template
  17.547 +    if (os::is_MP()) {
  17.548 +      $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
  17.549 +    } else {
  17.550 +      $$emit$$"MEMBAR-volatile ! (empty encoding)"
  17.551 +    }
  17.552 +  %}
  17.553 +  ins_encode %{
  17.554 +    __ membar(Assembler::StoreLoad);
  17.555 +  %}
  17.556    ins_pipe(pipe_slow);
  17.557  %}
  17.558  
  17.559 @@ -11558,27 +11823,52 @@
  17.560    ins_pipe(pipe_slow);
  17.561  %}
  17.562  
  17.563 -instruct string_compare(rdi_RegP str1, rsi_RegP str2, rax_RegI tmp1,
  17.564 -                        rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr)
  17.565 +instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
  17.566 +                        rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
  17.567  %{
  17.568    match(Set result (StrComp str1 str2));
  17.569 -  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr);
  17.570 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  17.571    //ins_cost(300);
  17.572  
  17.573    format %{ "String Compare $str1, $str2 -> $result    // XXX KILL RAX, RBX" %}
  17.574 -  ins_encode( enc_String_Compare() );
  17.575 +  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  17.576    ins_pipe( pipe_slow );
  17.577  %}
  17.578  
  17.579 +instruct string_indexof(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
  17.580 +                        rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr)
  17.581 +%{
  17.582 +  predicate(UseSSE42Intrinsics);
  17.583 +  match(Set result (StrIndexOf str1 str2));
  17.584 +  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
  17.585 +
  17.586 +  format %{ "String IndexOf $str1,$str2 -> $result   // KILL RAX, RCX, RDX" %}
  17.587 +  ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  17.588 +  ins_pipe( pipe_slow );
  17.589 +%}
  17.590 +
  17.591 +// fast string equals
  17.592 +instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3,
  17.593 +                       rcx_RegI tmp4, rax_RegI result, rFlagsReg cr)
  17.594 +%{
  17.595 +  match(Set result (StrEquals str1 str2));
  17.596 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
  17.597 +
  17.598 +  format %{ "String Equals $str1,$str2 -> $result    // KILL RBX, RCX" %}
  17.599 +  ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
  17.600 +  ins_pipe( pipe_slow );
  17.601 +%}
  17.602 +
  17.603  // fast array equals
  17.604 -instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, 
  17.605 -                      rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{
  17.606 +instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2, rax_RegI tmp3,
  17.607 +                      rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
  17.608 +%{
  17.609    match(Set result (AryEq ary1 ary2));
  17.610 -  effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
  17.611 +  effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
  17.612    //ins_cost(300);
  17.613  
  17.614 -  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL RAX, RBX" %}
  17.615 -  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
  17.616 +  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL RAX, RBX" %}
  17.617 +  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
  17.618    ins_pipe( pipe_slow );
  17.619  %}
  17.620  
    18.1 --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.hpp	Wed Apr 01 22:31:26 2009 -0700
    18.2 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.hpp	Thu Apr 02 17:01:00 2009 -0700
    18.3 @@ -29,13 +29,11 @@
    18.4    static jint  (*atomic_cmpxchg_func)     (jint,  volatile jint*,  jint);
    18.5    static jlong (*atomic_cmpxchg_long_func)(jlong, volatile jlong*, jlong);
    18.6    static jint  (*atomic_add_func)         (jint,  volatile jint*);
    18.7 -  static void  (*fence_func)              ();
    18.8  
    18.9    static jint  atomic_xchg_bootstrap        (jint,  volatile jint*);
   18.10    static jint  atomic_cmpxchg_bootstrap     (jint,  volatile jint*,  jint);
   18.11    static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong);
   18.12    static jint  atomic_add_bootstrap         (jint,  volatile jint*);
   18.13 -  static void  fence_bootstrap              ();
   18.14  
   18.15    static void setup_fpu() {}
   18.16  
    19.1 --- a/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp	Wed Apr 01 22:31:26 2009 -0700
    19.2 +++ b/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp	Thu Apr 02 17:01:00 2009 -0700
    19.3 @@ -44,11 +44,12 @@
    19.4  
    19.5  inline void OrderAccess::fence() {
    19.6    if (os::is_MP()) {
    19.7 +    // always use locked addl since mfence is sometimes expensive
    19.8  #ifdef AMD64
    19.9 -    __asm__ __volatile__ ("mfence":::"memory");
   19.10 +    __asm__ volatile ("lock; addl $0,0(%%rsp)" : : : "cc", "memory");
   19.11  #else
   19.12      __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
   19.13 -#endif // AMD64
   19.14 +#endif
   19.15    }
   19.16  }
   19.17  
    20.1 --- a/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp	Wed Apr 01 22:31:26 2009 -0700
    20.2 +++ b/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp	Thu Apr 02 17:01:00 2009 -0700
    20.3 @@ -60,22 +60,10 @@
    20.4    dummy = 0;
    20.5  }
    20.6  
    20.7 -#if defined(COMPILER2) || defined(_LP64)
    20.8 -
    20.9  inline void OrderAccess::fence() {
   20.10    _OrderAccess_fence();
   20.11  }
   20.12  
   20.13 -#else  // defined(COMPILER2) || defined(_LP64)
   20.14 -
   20.15 -inline void OrderAccess::fence() {
   20.16 -  if (os::is_MP()) {
   20.17 -    (*os::fence_func)();
   20.18 -  }
   20.19 -}
   20.20 -
   20.21 -#endif // defined(COMPILER2) || defined(_LP64)
   20.22 -
   20.23  #endif // _GNU_SOURCE
   20.24  
   20.25  inline jbyte    OrderAccess::load_acquire(volatile jbyte*   p) { return *p; }
    21.1 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Apr 01 22:31:26 2009 -0700
    21.2 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Apr 02 17:01:00 2009 -0700
    21.3 @@ -619,7 +619,6 @@
    21.4  typedef jint  cmpxchg_func_t     (jint,  volatile jint*,  jint);
    21.5  typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong);
    21.6  typedef jint  add_func_t         (jint,  volatile jint*);
    21.7 -typedef void  fence_func_t       ();
    21.8  
    21.9  jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) {
   21.10    // try to use the stub:
   21.11 @@ -681,25 +680,10 @@
   21.12    return (*dest) += add_value;
   21.13  }
   21.14  
   21.15 -void os::fence_bootstrap() {
   21.16 -  // try to use the stub:
   21.17 -  fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry());
   21.18 -
   21.19 -  if (func != NULL) {
   21.20 -    os::fence_func = func;
   21.21 -    (*func)();
   21.22 -    return;
   21.23 -  }
   21.24 -  assert(Threads::number_of_threads() == 0, "for bootstrap only");
   21.25 -
   21.26 -  // don't have to do anything for a single thread
   21.27 -}
   21.28 -
   21.29  xchg_func_t*         os::atomic_xchg_func         = os::atomic_xchg_bootstrap;
   21.30  cmpxchg_func_t*      os::atomic_cmpxchg_func      = os::atomic_cmpxchg_bootstrap;
   21.31  cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
   21.32  add_func_t*          os::atomic_add_func          = os::atomic_add_bootstrap;
   21.33 -fence_func_t*        os::fence_func               = os::fence_bootstrap;
   21.34  
   21.35  #endif // !_LP64 && !COMPILER2
   21.36  
    22.1 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.hpp	Wed Apr 01 22:31:26 2009 -0700
    22.2 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.hpp	Thu Apr 02 17:01:00 2009 -0700
    22.3 @@ -29,13 +29,11 @@
    22.4    static jint  (*atomic_cmpxchg_func)     (jint,  volatile jint*,  jint);
    22.5    static jlong (*atomic_cmpxchg_long_func)(jlong, volatile jlong*, jlong);
    22.6    static jint  (*atomic_add_func)         (jint,  volatile jint*);
    22.7 -  static void  (*fence_func)              ();
    22.8  
    22.9    static jint  atomic_xchg_bootstrap        (jint,  volatile jint*);
   22.10    static jint  atomic_cmpxchg_bootstrap     (jint,  volatile jint*,  jint);
   22.11    static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong);
   22.12    static jint  atomic_add_bootstrap         (jint,  volatile jint*);
   22.13 -  static void  fence_bootstrap              ();
   22.14  
   22.15    static void setup_fpu() {}
   22.16  
    23.1 --- a/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp	Wed Apr 01 22:31:26 2009 -0700
    23.2 +++ b/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp	Thu Apr 02 17:01:00 2009 -0700
    23.3 @@ -61,11 +61,8 @@
    23.4  #endif // AMD64
    23.5    }
    23.6    inline void _OrderAccess_fence() {
    23.7 -#ifdef AMD64
    23.8 -    __asm__ __volatile__ ("mfence":::"memory");
    23.9 -#else
   23.10 +    // Always use locked addl since mfence is sometimes expensive
   23.11      __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
   23.12 -#endif // AMD64
   23.13    }
   23.14  
   23.15  }
    24.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Apr 01 22:31:26 2009 -0700
    24.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Apr 02 17:01:00 2009 -0700
    24.3 @@ -794,7 +794,6 @@
    24.4  typedef jint  cmpxchg_func_t     (jint,  volatile jint*,  jint);
    24.5  typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong);
    24.6  typedef jint  add_func_t         (jint,  volatile jint*);
    24.7 -typedef void  fence_func_t       ();
    24.8  
    24.9  jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) {
   24.10    // try to use the stub:
   24.11 @@ -856,25 +855,10 @@
   24.12    return (*dest) += add_value;
   24.13  }
   24.14  
   24.15 -void os::fence_bootstrap() {
   24.16 -  // try to use the stub:
   24.17 -  fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry());
   24.18 -
   24.19 -  if (func != NULL) {
   24.20 -    os::fence_func = func;
   24.21 -    (*func)();
   24.22 -    return;
   24.23 -  }
   24.24 -  assert(Threads::number_of_threads() == 0, "for bootstrap only");
   24.25 -
   24.26 -  // don't have to do anything for a single thread
   24.27 -}
   24.28 -
   24.29  xchg_func_t*         os::atomic_xchg_func         = os::atomic_xchg_bootstrap;
   24.30  cmpxchg_func_t*      os::atomic_cmpxchg_func      = os::atomic_cmpxchg_bootstrap;
   24.31  cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
   24.32  add_func_t*          os::atomic_add_func          = os::atomic_add_bootstrap;
   24.33 -fence_func_t*        os::fence_func               = os::fence_bootstrap;
   24.34  
   24.35  extern "C" _solaris_raw_setup_fpu(address ptr);
   24.36  void os::setup_fpu() {
    25.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp	Wed Apr 01 22:31:26 2009 -0700
    25.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp	Thu Apr 02 17:01:00 2009 -0700
    25.3 @@ -32,13 +32,11 @@
    25.4    static jint  (*atomic_cmpxchg_func)     (jint,  volatile jint*,  jint);
    25.5    static jlong (*atomic_cmpxchg_long_func)(jlong, volatile jlong*, jlong);
    25.6    static jint  (*atomic_add_func)         (jint,  volatile jint*);
    25.7 -  static void  (*fence_func)              ();
    25.8  
    25.9    static jint  atomic_xchg_bootstrap        (jint,  volatile jint*);
   25.10    static jint  atomic_cmpxchg_bootstrap     (jint,  volatile jint*,  jint);
   25.11    static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong);
   25.12    static jint  atomic_add_bootstrap         (jint,  volatile jint*);
   25.13 -  static void  fence_bootstrap              ();
   25.14  
   25.15    static void setup_fpu();
   25.16  #endif // AMD64
    26.1 --- a/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp	Wed Apr 01 22:31:26 2009 -0700
    26.2 +++ b/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp	Thu Apr 02 17:01:00 2009 -0700
    26.3 @@ -46,7 +46,7 @@
    26.4  
    26.5  inline void OrderAccess::fence() {
    26.6  #ifdef AMD64
    26.7 -  (*os::fence_func)();
    26.8 +  StubRoutines_fence();
    26.9  #else
   26.10    if (os::is_MP()) {
   26.11      __asm {
    27.1 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Apr 01 22:31:26 2009 -0700
    27.2 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Thu Apr 02 17:01:00 2009 -0700
    27.3 @@ -196,7 +196,6 @@
    27.4  typedef jlong     cmpxchg_long_func_t    (jlong,    volatile jlong*, jlong);
    27.5  typedef jint      add_func_t             (jint,     volatile jint*);
    27.6  typedef intptr_t  add_ptr_func_t         (intptr_t, volatile intptr_t*);
    27.7 -typedef void      fence_func_t           ();
    27.8  
    27.9  #ifdef AMD64
   27.10  
   27.11 @@ -292,27 +291,11 @@
   27.12    return (*dest) += add_value;
   27.13  }
   27.14  
   27.15 -void os::fence_bootstrap() {
   27.16 -  // try to use the stub:
   27.17 -  fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry());
   27.18 -
   27.19 -  if (func != NULL) {
   27.20 -    os::fence_func = func;
   27.21 -    (*func)();
   27.22 -    return;
   27.23 -  }
   27.24 -  assert(Threads::number_of_threads() == 0, "for bootstrap only");
   27.25 -
   27.26 -  // don't have to do anything for a single thread
   27.27 -}
   27.28 -
   27.29 -
   27.30  xchg_func_t*         os::atomic_xchg_func         = os::atomic_xchg_bootstrap;
   27.31  xchg_ptr_func_t*     os::atomic_xchg_ptr_func     = os::atomic_xchg_ptr_bootstrap;
   27.32  cmpxchg_func_t*      os::atomic_cmpxchg_func      = os::atomic_cmpxchg_bootstrap;
   27.33  add_func_t*          os::atomic_add_func          = os::atomic_add_bootstrap;
   27.34  add_ptr_func_t*      os::atomic_add_ptr_func      = os::atomic_add_ptr_bootstrap;
   27.35 -fence_func_t*        os::fence_func               = os::fence_bootstrap;
   27.36  
   27.37  #endif // AMD64
   27.38  
    28.1 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.hpp	Wed Apr 01 22:31:26 2009 -0700
    28.2 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.hpp	Thu Apr 02 17:01:00 2009 -0700
    28.3 @@ -35,9 +35,6 @@
    28.4    static jint      (*atomic_add_func)           (jint,      volatile jint*);
    28.5    static intptr_t  (*atomic_add_ptr_func)       (intptr_t,  volatile intptr_t*);
    28.6  
    28.7 -  static void      (*fence_func)                ();
    28.8 -
    28.9 -
   28.10    static jint      atomic_xchg_bootstrap        (jint,      volatile jint*);
   28.11    static intptr_t  atomic_xchg_ptr_bootstrap    (intptr_t,  volatile intptr_t*);
   28.12  
   28.13 @@ -53,8 +50,6 @@
   28.14  #ifdef AMD64
   28.15    static jint      atomic_add_bootstrap         (jint,      volatile jint*);
   28.16    static intptr_t  atomic_add_ptr_bootstrap     (intptr_t,  volatile intptr_t*);
   28.17 -
   28.18 -  static void      fence_bootstrap              ();
   28.19  #endif // AMD64
   28.20  
   28.21    static void setup_fpu();
    29.1 --- a/src/share/vm/adlc/formssel.cpp	Wed Apr 01 22:31:26 2009 -0700
    29.2 +++ b/src/share/vm/adlc/formssel.cpp	Thu Apr 02 17:01:00 2009 -0700
    29.3 @@ -574,9 +574,13 @@
    29.4    // TEMPORARY
    29.5    // if( is_simple_chain_rule(globals) )  return false;
    29.6  
    29.7 -  // String-compare uses many memorys edges, but writes none
    29.8 +  // String.(compareTo/equals/indexOf) and Arrays.equals use many memorys edges,
    29.9 +  // but writes none
   29.10    if( _matrule && _matrule->_rChild &&
   29.11 -      strcmp(_matrule->_rChild->_opType,"StrComp")==0 )
   29.12 +      ( strcmp(_matrule->_rChild->_opType,"StrComp"    )==0 ||
   29.13 +        strcmp(_matrule->_rChild->_opType,"StrEquals"  )==0 ||
   29.14 +        strcmp(_matrule->_rChild->_opType,"StrIndexOf" )==0 ||
   29.15 +        strcmp(_matrule->_rChild->_opType,"AryEq"      )==0 ))
   29.16      return true;
   29.17  
   29.18    // Check if instruction has a USE of a memory operand class, but no defs
   29.19 @@ -815,8 +819,10 @@
   29.20      return AdlcVMDeps::Parms;   // Skip the machine-state edges
   29.21  
   29.22    if( _matrule->_rChild &&
   29.23 -          strcmp(_matrule->_rChild->_opType,"StrComp")==0 ) {
   29.24 -        // String compare takes 1 control and 4 memory edges.
   29.25 +      ( strcmp(_matrule->_rChild->_opType,"StrComp"   )==0 ||
   29.26 +        strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
   29.27 +        strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 )) {
   29.28 +        // String.(compareTo/equals/indexOf) take 1 control and 4 memory edges.
   29.29      return 5;
   29.30    }
   29.31  
    30.1 --- a/src/share/vm/asm/assembler.hpp	Wed Apr 01 22:31:26 2009 -0700
    30.2 +++ b/src/share/vm/asm/assembler.hpp	Thu Apr 02 17:01:00 2009 -0700
    30.3 @@ -1,5 +1,5 @@
    30.4  /*
    30.5 - * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
    30.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    30.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    30.8   *
    30.9   * This code is free software; you can redistribute it and/or modify it
   30.10 @@ -143,15 +143,15 @@
   30.11  // A union type for code which has to assemble both constant and
   30.12  // non-constant operands, when the distinction cannot be made
   30.13  // statically.
   30.14 -class RegisterConstant VALUE_OBJ_CLASS_SPEC {
   30.15 +class RegisterOrConstant VALUE_OBJ_CLASS_SPEC {
   30.16   private:
   30.17    Register _r;
   30.18    intptr_t _c;
   30.19  
   30.20   public:
   30.21 -  RegisterConstant(): _r(noreg), _c(0) {}
   30.22 -  RegisterConstant(Register r): _r(r), _c(0) {}
   30.23 -  RegisterConstant(intptr_t c): _r(noreg), _c(c) {}
   30.24 +  RegisterOrConstant(): _r(noreg), _c(0) {}
   30.25 +  RegisterOrConstant(Register r): _r(r), _c(0) {}
   30.26 +  RegisterOrConstant(intptr_t c): _r(noreg), _c(c) {}
   30.27  
   30.28    Register as_register() const { assert(is_register(),""); return _r; }
   30.29    intptr_t as_constant() const { assert(is_constant(),""); return _c; }
   30.30 @@ -310,13 +310,13 @@
   30.31    // offsets in code which must be generated before the object class is loaded.
   30.32    // Field offsets are never zero, since an object's header (mark word)
   30.33    // is located at offset zero.
   30.34 -  RegisterConstant delayed_value(int(*value_fn)(), Register tmp, int offset = 0) {
   30.35 -    return delayed_value(delayed_value_addr(value_fn), tmp, offset);
   30.36 +  RegisterOrConstant delayed_value(int(*value_fn)(), Register tmp, int offset = 0) {
   30.37 +    return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
   30.38    }
   30.39 -  RegisterConstant delayed_value(address(*value_fn)(), Register tmp, int offset = 0) {
   30.40 -    return delayed_value(delayed_value_addr(value_fn), tmp, offset);
   30.41 +  RegisterOrConstant delayed_value(address(*value_fn)(), Register tmp, int offset = 0) {
   30.42 +    return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
   30.43    }
   30.44 -  virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp, int offset) = 0;
   30.45 +  virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset) = 0;
   30.46    // Last overloading is platform-dependent; look in assembler_<arch>.cpp.
   30.47    static intptr_t* delayed_value_addr(int(*constant_fn)());
   30.48    static intptr_t* delayed_value_addr(address(*constant_fn)());
    31.1 --- a/src/share/vm/ci/ciTypeFlow.cpp	Wed Apr 01 22:31:26 2009 -0700
    31.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp	Thu Apr 02 17:01:00 2009 -0700
    31.3 @@ -2237,7 +2237,6 @@
    31.4    for (SuccIter iter(tail); !iter.done(); iter.next()) {
    31.5      if (iter.succ() == head) {
    31.6        iter.set_succ(clone);
    31.7 -      break;
    31.8      }
    31.9    }
   31.10    flow_block(tail, temp_vector, temp_set);
    32.1 --- a/src/share/vm/classfile/javaClasses.cpp	Wed Apr 01 22:31:26 2009 -0700
    32.2 +++ b/src/share/vm/classfile/javaClasses.cpp	Thu Apr 02 17:01:00 2009 -0700
    32.3 @@ -239,22 +239,20 @@
    32.4    typeArrayOop value  = java_lang_String::value(obj);
    32.5    int          offset = java_lang_String::offset(obj);
    32.6    int          length = java_lang_String::length(obj);
    32.7 -
    32.8 -  ResourceMark rm(THREAD);
    32.9 -  symbolHandle result;
   32.10 -
   32.11 -  if (length > 0) {
   32.12 -    int utf8_length = UNICODE::utf8_length(value->char_at_addr(offset), length);
   32.13 -    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
   32.14 -    UNICODE::convert_to_utf8(value->char_at_addr(offset), length, chars);
   32.15 -    // Allocate the symbol
   32.16 -    result = oopFactory::new_symbol_handle(chars, utf8_length, CHECK_(symbolHandle()));
   32.17 -  } else {
   32.18 -    result = oopFactory::new_symbol_handle("", 0, CHECK_(symbolHandle()));
   32.19 -  }
   32.20 -  return result;
   32.21 +  jchar* base = value->char_at_addr(offset);
   32.22 +  symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD);
   32.23 +  return symbolHandle(THREAD, sym);
   32.24  }
   32.25  
   32.26 +symbolOop java_lang_String::as_symbol_or_null(oop java_string) {
   32.27 +  typeArrayOop value  = java_lang_String::value(java_string);
   32.28 +  int          offset = java_lang_String::offset(java_string);
   32.29 +  int          length = java_lang_String::length(java_string);
   32.30 +  jchar* base = value->char_at_addr(offset);
   32.31 +  return SymbolTable::probe_unicode(base, length);
   32.32 +}
   32.33 +
   32.34 +
   32.35  int java_lang_String::utf8_length(oop java_string) {
   32.36    typeArrayOop value  = java_lang_String::value(java_string);
   32.37    int          offset = java_lang_String::offset(java_string);
   32.38 @@ -385,6 +383,48 @@
   32.39  }
   32.40  
   32.41  
   32.42 +void java_lang_Class::print_signature(oop java_class, outputStream* st) {
   32.43 +  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   32.44 +  symbolOop name = NULL;
   32.45 +  bool is_instance = false;
   32.46 +  if (is_primitive(java_class)) {
   32.47 +    name = vmSymbols::type_signature(primitive_type(java_class));
   32.48 +  } else {
   32.49 +    klassOop k = as_klassOop(java_class);
   32.50 +    is_instance = Klass::cast(k)->oop_is_instance();
   32.51 +    name = Klass::cast(k)->name();
   32.52 +  }
   32.53 +  if (name == NULL) {
   32.54 +    st->print("<null>");
   32.55 +    return;
   32.56 +  }
   32.57 +  if (is_instance)  st->print("L");
   32.58 +  st->write((char*) name->base(), (int) name->utf8_length());
   32.59 +  if (is_instance)  st->print(";");
   32.60 +}
   32.61 +
   32.62 +symbolOop java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) {
   32.63 +  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   32.64 +  symbolOop name = NULL;
   32.65 +  if (is_primitive(java_class)) {
   32.66 +    return vmSymbols::type_signature(primitive_type(java_class));
   32.67 +  } else {
   32.68 +    klassOop k = as_klassOop(java_class);
   32.69 +    if (!Klass::cast(k)->oop_is_instance()) {
   32.70 +      return Klass::cast(k)->name();
   32.71 +    } else {
   32.72 +      ResourceMark rm;
   32.73 +      const char* sigstr = Klass::cast(k)->signature_name();
   32.74 +      int         siglen = (int) strlen(sigstr);
   32.75 +      if (!intern_if_not_found)
   32.76 +        return SymbolTable::probe(sigstr, siglen);
   32.77 +      else
   32.78 +        return oopFactory::new_symbol(sigstr, siglen, THREAD);
   32.79 +    }
   32.80 +  }
   32.81 +}
   32.82 +
   32.83 +
   32.84  klassOop java_lang_Class::array_klass(oop java_class) {
   32.85    klassOop k = klassOop(java_class->obj_field(array_klass_offset));
   32.86    assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_javaArray(), "should be array klass");
   32.87 @@ -412,6 +452,8 @@
   32.88  
   32.89  
   32.90  bool java_lang_Class::is_primitive(oop java_class) {
   32.91 +  // should assert:
   32.92 +  //assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   32.93    klassOop k = klassOop(java_class->obj_field(klass_offset));
   32.94    return k == NULL;
   32.95  }
   32.96 @@ -431,6 +473,19 @@
   32.97    return type;
   32.98  }
   32.99  
  32.100 +BasicType java_lang_Class::as_BasicType(oop java_class, klassOop* reference_klass) {
  32.101 +  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
  32.102 +  if (is_primitive(java_class)) {
  32.103 +    if (reference_klass != NULL)
  32.104 +      (*reference_klass) = NULL;
  32.105 +    return primitive_type(java_class);
  32.106 +  } else {
  32.107 +    if (reference_klass != NULL)
  32.108 +      (*reference_klass) = as_klassOop(java_class);
  32.109 +    return T_OBJECT;
  32.110 +  }
  32.111 +}
  32.112 +
  32.113  
  32.114  oop java_lang_Class::primitive_mirror(BasicType t) {
  32.115    oop mirror = Universe::java_mirror(t);
  32.116 @@ -1988,6 +2043,21 @@
  32.117  }
  32.118  
  32.119  
  32.120 +void java_lang_boxing_object::print(BasicType type, jvalue* value, outputStream* st) {
  32.121 +  switch (type) {
  32.122 +  case T_BOOLEAN:   st->print("%s", value->z ? "true" : "false");   break;
  32.123 +  case T_CHAR:      st->print("%d", value->c);                      break;
  32.124 +  case T_BYTE:      st->print("%d", value->b);                      break;
  32.125 +  case T_SHORT:     st->print("%d", value->s);                      break;
  32.126 +  case T_INT:       st->print("%d", value->i);                      break;
  32.127 +  case T_LONG:      st->print(INT64_FORMAT, value->j);              break;
  32.128 +  case T_FLOAT:     st->print("%f", value->f);                      break;
  32.129 +  case T_DOUBLE:    st->print("%lf", value->d);                     break;
  32.130 +  default:          st->print("type %d?", type);                    break;
  32.131 +  }
  32.132 +}
  32.133 +
  32.134 +
  32.135  // Support for java_lang_ref_Reference
  32.136  oop java_lang_ref_Reference::pending_list_lock() {
  32.137    instanceKlass* ik = instanceKlass::cast(SystemDictionary::reference_klass());
    33.1 --- a/src/share/vm/classfile/javaClasses.hpp	Wed Apr 01 22:31:26 2009 -0700
    33.2 +++ b/src/share/vm/classfile/javaClasses.hpp	Thu Apr 02 17:01:00 2009 -0700
    33.3 @@ -107,6 +107,7 @@
    33.4  
    33.5    // Conversion
    33.6    static symbolHandle as_symbol(Handle java_string, TRAPS);
    33.7 +  static symbolOop as_symbol_or_null(oop java_string);
    33.8  
    33.9    // Testers
   33.10    static bool is_instance(oop obj) {
   33.11 @@ -149,6 +150,9 @@
   33.12    static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
   33.13    // Conversion
   33.14    static klassOop as_klassOop(oop java_class);
   33.15 +  static BasicType as_BasicType(oop java_class, klassOop* reference_klass = NULL);
   33.16 +  static symbolOop as_signature(oop java_class, bool intern_if_not_found, TRAPS);
   33.17 +  static void print_signature(oop java_class, outputStream *st);
   33.18    // Testing
   33.19    static bool is_instance(oop obj) {
   33.20      return obj != NULL && obj->klass() == SystemDictionary::class_klass();
   33.21 @@ -668,6 +672,8 @@
   33.22    static BasicType basic_type(oop box);
   33.23    static bool is_instance(oop box)                 { return basic_type(box) != T_ILLEGAL; }
   33.24    static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
   33.25 +  static void print(oop box, outputStream* st)     { jvalue value;  print(get_value(box, &value), &value, st); }
   33.26 +  static void print(BasicType type, jvalue* value, outputStream* st);
   33.27  
   33.28    static int value_offset_in_bytes(BasicType type) {
   33.29      return ( type == T_LONG || type == T_DOUBLE ) ? long_value_offset :
    34.1 --- a/src/share/vm/classfile/loaderConstraints.hpp	Wed Apr 01 22:31:26 2009 -0700
    34.2 +++ b/src/share/vm/classfile/loaderConstraints.hpp	Thu Apr 02 17:01:00 2009 -0700
    34.3 @@ -1,5 +1,5 @@
    34.4  /*
    34.5 - * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
    34.6 + * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
    34.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    34.8   *
    34.9   * This code is free software; you can redistribute it and/or modify it
   34.10 @@ -60,8 +60,10 @@
   34.11    bool add_entry(symbolHandle name, klassOop klass1, Handle loader1,
   34.12                                      klassOop klass2, Handle loader2);
   34.13  
   34.14 -  void check_signature_loaders(symbolHandle signature, Handle loader1,
   34.15 -                               Handle loader2, bool is_method, TRAPS);
   34.16 +  // Note:  The main entry point for this module is via SystemDictionary.
   34.17 +  // SystemDictionary::check_signature_loaders(symbolHandle signature,
   34.18 +  //                                           Handle loader1, Handle loader2,
   34.19 +  //                                           bool is_method, TRAPS)
   34.20  
   34.21    klassOop find_constrained_klass(symbolHandle name, Handle loader);
   34.22    klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name,
    35.1 --- a/src/share/vm/classfile/symbolTable.cpp	Wed Apr 01 22:31:26 2009 -0700
    35.2 +++ b/src/share/vm/classfile/symbolTable.cpp	Thu Apr 02 17:01:00 2009 -0700
    35.3 @@ -1,5 +1,5 @@
    35.4  /*
    35.5 - * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
    35.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    35.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    35.8   *
    35.9   * This code is free software; you can redistribute it and/or modify it
   35.10 @@ -109,6 +109,40 @@
   35.11    return the_table()->lookup(index, name, len, hash);
   35.12  }
   35.13  
   35.14 +// Suggestion: Push unicode-based lookup all the way into the hashing
   35.15 +// and probing logic, so there is no need for convert_to_utf8 until
   35.16 +// an actual new symbolOop is created.
   35.17 +symbolOop SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
   35.18 +  int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   35.19 +  char stack_buf[128];
   35.20 +  if (utf8_length < (int) sizeof(stack_buf)) {
   35.21 +    char* chars = stack_buf;
   35.22 +    UNICODE::convert_to_utf8(name, utf16_length, chars);
   35.23 +    return lookup(chars, utf8_length, THREAD);
   35.24 +  } else {
   35.25 +    ResourceMark rm(THREAD);
   35.26 +    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
   35.27 +    UNICODE::convert_to_utf8(name, utf16_length, chars);
   35.28 +    return lookup(chars, utf8_length, THREAD);
   35.29 +  }
   35.30 +}
   35.31 +
   35.32 +symbolOop SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
   35.33 +                                           unsigned int& hash) {
   35.34 +  int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   35.35 +  char stack_buf[128];
   35.36 +  if (utf8_length < (int) sizeof(stack_buf)) {
   35.37 +    char* chars = stack_buf;
   35.38 +    UNICODE::convert_to_utf8(name, utf16_length, chars);
   35.39 +    return lookup_only(chars, utf8_length, hash);
   35.40 +  } else {
   35.41 +    ResourceMark rm;
   35.42 +    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
   35.43 +    UNICODE::convert_to_utf8(name, utf16_length, chars);
   35.44 +    return lookup_only(chars, utf8_length, hash);
   35.45 +  }
   35.46 +}
   35.47 +
   35.48  void SymbolTable::add(constantPoolHandle cp, int names_count,
   35.49                        const char** names, int* lengths, int* cp_indices,
   35.50                        unsigned int* hashValues, TRAPS) {
   35.51 @@ -126,15 +160,6 @@
   35.52    }
   35.53  }
   35.54  
   35.55 -// Needed for preloading classes in signatures when compiling.
   35.56 -
   35.57 -symbolOop SymbolTable::probe(const char* name, int len) {
   35.58 -  unsigned int hashValue = hash_symbol(name, len);
   35.59 -  int index = the_table()->hash_to_index(hashValue);
   35.60 -  return the_table()->lookup(index, name, len, hashValue);
   35.61 -}
   35.62 -
   35.63 -
   35.64  symbolOop SymbolTable::basic_add(int index, u1 *name, int len,
   35.65                                   unsigned int hashValue, TRAPS) {
   35.66    assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
    36.1 --- a/src/share/vm/classfile/symbolTable.hpp	Wed Apr 01 22:31:26 2009 -0700
    36.2 +++ b/src/share/vm/classfile/symbolTable.hpp	Thu Apr 02 17:01:00 2009 -0700
    36.3 @@ -1,5 +1,5 @@
    36.4  /*
    36.5 - * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
    36.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    36.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    36.8   *
    36.9   * This code is free software; you can redistribute it and/or modify it
   36.10 @@ -91,6 +91,10 @@
   36.11    // Only copy to C string to be added if lookup failed.
   36.12    static symbolOop lookup(symbolHandle sym, int begin, int end, TRAPS);
   36.13  
   36.14 +  // jchar (utf16) version of lookups
   36.15 +  static symbolOop lookup_unicode(const jchar* name, int len, TRAPS);
   36.16 +  static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
   36.17 +
   36.18    static void add(constantPoolHandle cp, int names_count,
   36.19                    const char** names, int* lengths, int* cp_indices,
   36.20                    unsigned int* hashValues, TRAPS);
   36.21 @@ -112,7 +116,14 @@
   36.22    // Needed for preloading classes in signatures when compiling.
   36.23    // Returns the symbol is already present in symbol table, otherwise
   36.24    // NULL.  NO ALLOCATION IS GUARANTEED!
   36.25 -  static symbolOop probe(const char* name, int len);
   36.26 +  static symbolOop probe(const char* name, int len) {
   36.27 +    unsigned int ignore_hash;
   36.28 +    return lookup_only(name, len, ignore_hash);
   36.29 +  }
   36.30 +  static symbolOop probe_unicode(const jchar* name, int len) {
   36.31 +    unsigned int ignore_hash;
   36.32 +    return lookup_only_unicode(name, len, ignore_hash);
   36.33 +  }
   36.34  
   36.35    // Histogram
   36.36    static void print_histogram()     PRODUCT_RETURN;
    37.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Wed Apr 01 22:31:26 2009 -0700
    37.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Apr 02 17:01:00 2009 -0700
    37.3 @@ -1964,6 +1964,13 @@
    37.4    return T_OBJECT;
    37.5  }
    37.6  
    37.7 +KlassHandle SystemDictionaryHandles::box_klass(BasicType t) {
    37.8 +  if (t >= T_BOOLEAN && t <= T_VOID)
    37.9 +    return KlassHandle(&SystemDictionary::_box_klasses[t], true);
   37.10 +  else
   37.11 +    return KlassHandle();
   37.12 +}
   37.13 +
   37.14  // Constraints on class loaders. The details of the algorithm can be
   37.15  // found in the OOPSLA'98 paper "Dynamic Class Loading in the Java
   37.16  // Virtual Machine" by Sheng Liang and Gilad Bracha.  The basic idea is
   37.17 @@ -2174,11 +2181,56 @@
   37.18  }
   37.19  
   37.20  
   37.21 +// Signature constraints ensure that callers and callees agree about
   37.22 +// the meaning of type names in their signatures.  This routine is the
   37.23 +// intake for constraints.  It collects them from several places:
   37.24 +//
   37.25 +//  * LinkResolver::resolve_method (if check_access is true) requires
   37.26 +//    that the resolving class (the caller) and the defining class of
   37.27 +//    the resolved method (the callee) agree on each type in the
   37.28 +//    method's signature.
   37.29 +//
   37.30 +//  * LinkResolver::resolve_interface_method performs exactly the same
   37.31 +//    checks.
   37.32 +//
   37.33 +//  * LinkResolver::resolve_field requires that the constant pool
   37.34 +//    attempting to link to a field agree with the field's defining
   37.35 +//    class about the type of the field signature.
   37.36 +//
   37.37 +//  * klassVtable::initialize_vtable requires that, when a class
   37.38 +//    overrides a vtable entry allocated by a superclass, that the
   37.39 +//    overriding method (i.e., the callee) agree with the superclass
   37.40 +//    on each type in the method's signature.
   37.41 +//
   37.42 +//  * klassItable::initialize_itable requires that, when a class fills
   37.43 +//    in its itables, for each non-abstract method installed in an
   37.44 +//    itable, the method (i.e., the callee) agree with the interface
   37.45 +//    on each type in the method's signature.
   37.46 +//
   37.47 +// All those methods have a boolean (check_access, checkconstraints)
   37.48 +// which turns off the checks.  This is used from specialized contexts
   37.49 +// such as bootstrapping, dumping, and debugging.
   37.50 +//
   37.51 +// No direct constraint is placed between the class and its
   37.52 +// supertypes.  Constraints are only placed along linked relations
   37.53 +// between callers and callees.  When a method overrides or implements
   37.54 +// an abstract method in a supertype (superclass or interface), the
   37.55 +// constraints are placed as if the supertype were the caller to the
   37.56 +// overriding method.  (This works well, since callers to the
   37.57 +// supertype have already established agreement between themselves and
   37.58 +// the supertype.)  As a result of all this, a class can disagree with
   37.59 +// its supertype about the meaning of a type name, as long as that
   37.60 +// class neither calls a relevant method of the supertype, nor is
   37.61 +// called (perhaps via an override) from the supertype.
   37.62 +//
   37.63 +//
   37.64 +// SystemDictionary::check_signature_loaders(sig, l1, l2)
   37.65 +//
   37.66  // Make sure all class components (including arrays) in the given
   37.67  // signature will be resolved to the same class in both loaders.
   37.68  // Returns the name of the type that failed a loader constraint check, or
   37.69  // NULL if no constraint failed. The returned C string needs cleaning up
   37.70 -// with a ResourceMark in the caller
   37.71 +// with a ResourceMark in the caller.  No exception except OOME is thrown.
   37.72  char* SystemDictionary::check_signature_loaders(symbolHandle signature,
   37.73                                                 Handle loader1, Handle loader2,
   37.74                                                 bool is_method, TRAPS)  {
    38.1 --- a/src/share/vm/classfile/systemDictionary.hpp	Wed Apr 01 22:31:26 2009 -0700
    38.2 +++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Apr 02 17:01:00 2009 -0700
    38.3 @@ -161,6 +161,7 @@
    38.4  class SystemDictionary : AllStatic {
    38.5    friend class VMStructs;
    38.6    friend class CompactingPermGenGen;
    38.7 +  friend class SystemDictionaryHandles;
    38.8    NOT_PRODUCT(friend class instanceKlassKlass;)
    38.9  
   38.10   public:
   38.11 @@ -595,3 +596,18 @@
   38.12    static bool _has_loadClassInternal;
   38.13    static bool _has_checkPackageAccess;
   38.14  };
   38.15 +
   38.16 +// Cf. vmSymbols vs. vmSymbolHandles
   38.17 +class SystemDictionaryHandles : AllStatic {
   38.18 +public:
   38.19 +  #define WK_KLASS_HANDLE_DECLARE(name, ignore_symbol, option) \
   38.20 +    static KlassHandle name() { \
   38.21 +      SystemDictionary::name(); \
   38.22 +      klassOop* loc = &SystemDictionary::_well_known_klasses[SystemDictionary::WK_KLASS_ENUM_NAME(name)]; \
   38.23 +      return KlassHandle(loc, true); \
   38.24 +    }
   38.25 +  WK_KLASSES_DO(WK_KLASS_HANDLE_DECLARE);
   38.26 +  #undef WK_KLASS_HANDLE_DECLARE
   38.27 +
   38.28 +  static KlassHandle box_klass(BasicType t);
   38.29 +};
    39.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Wed Apr 01 22:31:26 2009 -0700
    39.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 02 17:01:00 2009 -0700
    39.3 @@ -49,6 +49,8 @@
    39.4    template(java_lang_Object,                          "java/lang/Object")                         \
    39.5    template(java_lang_Class,                           "java/lang/Class")                          \
    39.6    template(java_lang_String,                          "java/lang/String")                         \
    39.7 +  template(java_lang_StringValue,                     "java/lang/StringValue")                    \
    39.8 +  template(java_lang_StringCache,                     "java/lang/StringValue$StringCache")        \
    39.9    template(java_lang_Thread,                          "java/lang/Thread")                         \
   39.10    template(java_lang_ThreadGroup,                     "java/lang/ThreadGroup")                    \
   39.11    template(java_lang_Cloneable,                       "java/lang/Cloneable")                      \
   39.12 @@ -285,6 +287,8 @@
   39.13    template(frontCacheEnabled_name,                    "frontCacheEnabled")                        \
   39.14    template(stringCacheEnabled_name,                   "stringCacheEnabled")                       \
   39.15    template(bitCount_name,                             "bitCount")                                 \
   39.16 +  template(profile_name,                              "profile")                                  \
   39.17 +  template(equals_name,                               "equals")                                   \
   39.18                                                                                                    \
   39.19    /* non-intrinsic name/signature pairs: */                                                       \
   39.20    template(register_method_name,                      "register")                                 \
   39.21 @@ -576,7 +580,6 @@
   39.22     do_signature(copyOfRange_signature,        "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;")            \
   39.23                                                                                                                          \
   39.24    do_intrinsic(_equalsC,                  java_util_Arrays,       equals_name,    equalsC_signature,             F_S)   \
   39.25 -   do_name(     equals_name,                                     "equals")                                              \
   39.26     do_signature(equalsC_signature,                               "([C[C)Z")                                             \
   39.27                                                                                                                          \
   39.28    do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
   39.29 @@ -586,6 +589,7 @@
   39.30     do_name(     compareTo_name,                                  "compareTo")                                           \
   39.31    do_intrinsic(_indexOf,                  java_lang_String,       indexOf_name, string_int_signature,            F_R)   \
   39.32     do_name(     indexOf_name,                                    "indexOf")                                             \
   39.33 +  do_intrinsic(_equals,                   java_lang_String,       equals_name, object_boolean_signature,         F_R)   \
   39.34                                                                                                                          \
   39.35    do_class(java_nio_Buffer,               "java/nio/Buffer")                                                            \
   39.36    do_intrinsic(_checkIndex,               java_nio_Buffer,        checkIndex_name, int_int_signature,            F_R)   \
    40.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Apr 01 22:31:26 2009 -0700
    40.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Apr 02 17:01:00 2009 -0700
    40.3 @@ -3847,7 +3847,7 @@
    40.4    MutexLockerEx ml(ovflw_stk->par_lock(),
    40.5                     Mutex::_no_safepoint_check_flag);
    40.6    // Grab up to 1/4 the size of the work queue
    40.7 -  size_t num = MIN2((size_t)work_q->max_elems()/4,
    40.8 +  size_t num = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
    40.9                      (size_t)ParGCDesiredObjsFromOverflowList);
   40.10    num = MIN2(num, ovflw_stk->length());
   40.11    for (int i = (int) num; i > 0; i--) {
   40.12 @@ -5204,13 +5204,12 @@
   40.13    NOT_PRODUCT(int num_steals = 0;)
   40.14    oop obj_to_scan;
   40.15    CMSBitMap* bm = &(_collector->_markBitMap);
   40.16 -  size_t num_from_overflow_list =
   40.17 -           MIN2((size_t)work_q->max_elems()/4,
   40.18 -                (size_t)ParGCDesiredObjsFromOverflowList);
   40.19  
   40.20    while (true) {
   40.21      // Completely finish any left over work from (an) earlier round(s)
   40.22      cl->trim_queue(0);
   40.23 +    size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
   40.24 +                                         (size_t)ParGCDesiredObjsFromOverflowList);
   40.25      // Now check if there's any work in the overflow list
   40.26      if (_collector->par_take_from_overflow_list(num_from_overflow_list,
   40.27                                                  work_q)) {
   40.28 @@ -5622,13 +5621,12 @@
   40.29    OopTaskQueue* work_q = work_queue(i);
   40.30    NOT_PRODUCT(int num_steals = 0;)
   40.31    oop obj_to_scan;
   40.32 -  size_t num_from_overflow_list =
   40.33 -           MIN2((size_t)work_q->max_elems()/4,
   40.34 -                (size_t)ParGCDesiredObjsFromOverflowList);
   40.35  
   40.36    while (true) {
   40.37      // Completely finish any left over work from (an) earlier round(s)
   40.38      drain->trim_queue(0);
   40.39 +    size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
   40.40 +                                         (size_t)ParGCDesiredObjsFromOverflowList);
   40.41      // Now check if there's any work in the overflow list
   40.42      if (_collector->par_take_from_overflow_list(num_from_overflow_list,
   40.43                                                  work_q)) {
   40.44 @@ -9021,7 +9019,7 @@
   40.45  // Transfer some number of overflown objects to usual marking
   40.46  // stack. Return true if some objects were transferred.
   40.47  bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
   40.48 -  size_t num = MIN2((size_t)_mark_stack->capacity()/4,
   40.49 +  size_t num = MIN2((size_t)(_mark_stack->capacity() - _mark_stack->length())/4,
   40.50                      (size_t)ParGCDesiredObjsFromOverflowList);
   40.51  
   40.52    bool res = _collector->take_from_overflow_list(num, _mark_stack);
    41.1 --- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Wed Apr 01 22:31:26 2009 -0700
    41.2 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Thu Apr 02 17:01:00 2009 -0700
    41.3 @@ -277,8 +277,6 @@
    41.4      gclog_or_tty->print("H: ");
    41.5    if (hr->in_collection_set())
    41.6      gclog_or_tty->print("CS: ");
    41.7 -  if (hr->popular())
    41.8 -    gclog_or_tty->print("pop: ");
    41.9    gclog_or_tty->print_cr("Region " PTR_FORMAT " (%s%s) "
   41.10                           "[" PTR_FORMAT ", " PTR_FORMAT"] "
   41.11                           "Used: " SIZE_FORMAT "K, garbage: " SIZE_FORMAT "K.",
    42.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Apr 01 22:31:26 2009 -0700
    42.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Apr 02 17:01:00 2009 -0700
    42.3 @@ -42,21 +42,6 @@
    42.4  
    42.5  // Local to this file.
    42.6  
    42.7 -// Finds the first HeapRegion.
    42.8 -// No longer used, but might be handy someday.
    42.9 -
   42.10 -class FindFirstRegionClosure: public HeapRegionClosure {
   42.11 -  HeapRegion* _a_region;
   42.12 -public:
   42.13 -  FindFirstRegionClosure() : _a_region(NULL) {}
   42.14 -  bool doHeapRegion(HeapRegion* r) {
   42.15 -    _a_region = r;
   42.16 -    return true;
   42.17 -  }
   42.18 -  HeapRegion* result() { return _a_region; }
   42.19 -};
   42.20 -
   42.21 -
   42.22  class RefineCardTableEntryClosure: public CardTableEntryClosure {
   42.23    SuspendibleThreadSet* _sts;
   42.24    G1RemSet* _g1rs;
   42.25 @@ -1207,13 +1192,12 @@
   42.26                                                     bool par) {
   42.27    assert(!hr->continuesHumongous(), "should have filtered these out");
   42.28    size_t res = 0;
   42.29 -  if (!hr->popular() && hr->used() > 0 && hr->garbage_bytes() == hr->used()) {
   42.30 -    if (!hr->is_young()) {
   42.31 -      if (G1PolicyVerbose > 0)
   42.32 -        gclog_or_tty->print_cr("Freeing empty region "PTR_FORMAT "(" SIZE_FORMAT " bytes)"
   42.33 -                               " during cleanup", hr, hr->used());
   42.34 -      free_region_work(hr, pre_used, cleared_h, freed_regions, list, par);
   42.35 -    }
   42.36 +  if (hr->used() > 0 && hr->garbage_bytes() == hr->used() &&
   42.37 +      !hr->is_young()) {
   42.38 +    if (G1PolicyVerbose > 0)
   42.39 +      gclog_or_tty->print_cr("Freeing empty region "PTR_FORMAT "(" SIZE_FORMAT " bytes)"
   42.40 +                                                                               " during cleanup", hr, hr->used());
   42.41 +    free_region_work(hr, pre_used, cleared_h, freed_regions, list, par);
   42.42    }
   42.43  }
   42.44  
   42.45 @@ -1342,10 +1326,6 @@
   42.46    _refine_cte_cl(NULL),
   42.47    _free_region_list(NULL), _free_region_list_size(0),
   42.48    _free_regions(0),
   42.49 -  _popular_object_boundary(NULL),
   42.50 -  _cur_pop_hr_index(0),
   42.51 -  _popular_regions_to_be_evacuated(NULL),
   42.52 -  _pop_obj_rc_at_copy(),
   42.53    _full_collection(false),
   42.54    _unclean_region_list(),
   42.55    _unclean_regions_coming(false),
   42.56 @@ -1520,26 +1500,11 @@
   42.57      _czft = new ConcurrentZFThread();
   42.58    }
   42.59  
   42.60 -
   42.61 -
   42.62 -  // Allocate the popular regions; take them off free lists.
   42.63 -  size_t pop_byte_size = G1NumPopularRegions * HeapRegion::GrainBytes;
   42.64 -  expand(pop_byte_size);
   42.65 -  _popular_object_boundary =
   42.66 -    _g1_reserved.start() + (G1NumPopularRegions * HeapRegion::GrainWords);
   42.67 -  for (int i = 0; i < G1NumPopularRegions; i++) {
   42.68 -    HeapRegion* hr = newAllocRegion(HeapRegion::GrainWords);
   42.69 -    //    assert(hr != NULL && hr->bottom() < _popular_object_boundary,
   42.70 -    //     "Should be enough, and all should be below boundary.");
   42.71 -    hr->set_popular(true);
   42.72 -  }
   42.73 -  assert(_cur_pop_hr_index == 0, "Start allocating at the first region.");
   42.74 -
   42.75    // Initialize the from_card cache structure of HeapRegionRemSet.
   42.76    HeapRegionRemSet::init_heap(max_regions());
   42.77  
   42.78 -  // Now expand into the rest of the initial heap size.
   42.79 -  expand(init_byte_size - pop_byte_size);
   42.80 +  // Now expand into the initial heap size.
   42.81 +  expand(init_byte_size);
   42.82  
   42.83    // Perform any initialization actions delegated to the policy.
   42.84    g1_policy()->init();
   42.85 @@ -1654,8 +1619,7 @@
   42.86  class SumUsedRegionsClosure: public HeapRegionClosure {
   42.87    size_t _num;
   42.88  public:
   42.89 -  // _num is set to 1 to account for the popular region
   42.90 -  SumUsedRegionsClosure() : _num(G1NumPopularRegions) {}
   42.91 +  SumUsedRegionsClosure() : _num(0) {}
   42.92    bool doHeapRegion(HeapRegion* r) {
   42.93      if (r->continuesHumongous() || r->used() > 0 || r->is_gc_alloc_region()) {
   42.94        _num += 1;
   42.95 @@ -1758,14 +1722,20 @@
   42.96    }
   42.97  };
   42.98  
   42.99 -void G1CollectedHeap::oop_iterate(OopClosure* cl) {
  42.100 +void G1CollectedHeap::oop_iterate(OopClosure* cl, bool do_perm) {
  42.101    IterateOopClosureRegionClosure blk(_g1_committed, cl);
  42.102    _hrs->iterate(&blk);
  42.103 +  if (do_perm) {
  42.104 +    perm_gen()->oop_iterate(cl);
  42.105 +  }
  42.106  }
  42.107  
  42.108 -void G1CollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl) {
  42.109 +void G1CollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl, bool do_perm) {
  42.110    IterateOopClosureRegionClosure blk(mr, cl);
  42.111    _hrs->iterate(&blk);
  42.112 +  if (do_perm) {
  42.113 +    perm_gen()->oop_iterate(cl);
  42.114 +  }
  42.115  }
  42.116  
  42.117  // Iterates an ObjectClosure over all objects within a HeapRegion.
  42.118 @@ -1782,9 +1752,12 @@
  42.119    }
  42.120  };
  42.121  
  42.122 -void G1CollectedHeap::object_iterate(ObjectClosure* cl) {
  42.123 +void G1CollectedHeap::object_iterate(ObjectClosure* cl, bool do_perm) {
  42.124    IterateObjectClosureRegionClosure blk(cl);
  42.125    _hrs->iterate(&blk);
  42.126 +  if (do_perm) {
  42.127 +    perm_gen()->object_iterate(cl);
  42.128 +  }
  42.129  }
  42.130  
  42.131  void G1CollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) {
  42.132 @@ -2318,9 +2291,6 @@
  42.133    if (SummarizeG1ZFStats) {
  42.134      ConcurrentZFThread::print_summary_info();
  42.135    }
  42.136 -  if (G1SummarizePopularity) {
  42.137 -    print_popularity_summary_info();
  42.138 -  }
  42.139    g1_policy()->print_yg_surv_rate_info();
  42.140  
  42.141    GCOverheadReporter::printGCOverhead();
  42.142 @@ -2414,7 +2384,7 @@
  42.143      VerifyMarkedObjsClosure verifycl(this);
  42.144      //    MutexLockerEx x(getMarkBitMapLock(),
  42.145      //              Mutex::_no_safepoint_check_flag);
  42.146 -    object_iterate(&verifycl);
  42.147 +    object_iterate(&verifycl, false);
  42.148  }
  42.149  
  42.150  void G1CollectedHeap::do_sync_mark() {
  42.151 @@ -2495,30 +2465,19 @@
  42.152  // </NEW PREDICTION>
  42.153  
  42.154  void
  42.155 -G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) {
  42.156 +G1CollectedHeap::do_collection_pause_at_safepoint() {
  42.157    char verbose_str[128];
  42.158    sprintf(verbose_str, "GC pause ");
  42.159 -  if (popular_region != NULL)
  42.160 -    strcat(verbose_str, "(popular)");
  42.161 -  else if (g1_policy()->in_young_gc_mode()) {
  42.162 +  if (g1_policy()->in_young_gc_mode()) {
  42.163      if (g1_policy()->full_young_gcs())
  42.164        strcat(verbose_str, "(young)");
  42.165      else
  42.166        strcat(verbose_str, "(partial)");
  42.167    }
  42.168 -  bool reset_should_initiate_conc_mark = false;
  42.169 -  if (popular_region != NULL && g1_policy()->should_initiate_conc_mark()) {
  42.170 -    // we currently do not allow an initial mark phase to be piggy-backed
  42.171 -    // on a popular pause
  42.172 -    reset_should_initiate_conc_mark = true;
  42.173 -    g1_policy()->unset_should_initiate_conc_mark();
  42.174 -  }
  42.175    if (g1_policy()->should_initiate_conc_mark())
  42.176      strcat(verbose_str, " (initial-mark)");
  42.177  
  42.178 -  GCCauseSetter x(this, (popular_region == NULL ?
  42.179 -                         GCCause::_g1_inc_collection_pause :
  42.180 -                         GCCause::_g1_pop_region_collection_pause));
  42.181 +  GCCauseSetter x(this, GCCause::_g1_inc_collection_pause);
  42.182  
  42.183    // if PrintGCDetails is on, we'll print long statistics information
  42.184    // in the collector policy code, so let's not print this as the output
  42.185 @@ -2609,7 +2568,7 @@
  42.186      save_marks();
  42.187  
  42.188      // We must do this before any possible evacuation that should propagate
  42.189 -    // marks, including evacuation of popular objects in a popular pause.
  42.190 +    // marks.
  42.191      if (mark_in_progress()) {
  42.192        double start_time_sec = os::elapsedTime();
  42.193  
  42.194 @@ -2626,29 +2585,15 @@
  42.195  
  42.196      assert(regions_accounted_for(), "Region leakage.");
  42.197  
  42.198 -    bool abandoned = false;
  42.199 -
  42.200      if (mark_in_progress())
  42.201        concurrent_mark()->newCSet();
  42.202  
  42.203      // Now choose the CS.
  42.204 -    if (popular_region == NULL) {
  42.205 -      g1_policy()->choose_collection_set();
  42.206 -    } else {
  42.207 -      // We may be evacuating a single region (for popularity).
  42.208 -      g1_policy()->record_popular_pause_preamble_start();
  42.209 -      popularity_pause_preamble(popular_region);
  42.210 -      g1_policy()->record_popular_pause_preamble_end();
  42.211 -      abandoned = (g1_policy()->collection_set() == NULL);
  42.212 -      // Now we allow more regions to be added (we have to collect
  42.213 -      // all popular regions).
  42.214 -      if (!abandoned) {
  42.215 -        g1_policy()->choose_collection_set(popular_region);
  42.216 -      }
  42.217 -    }
  42.218 +    g1_policy()->choose_collection_set();
  42.219 +
  42.220      // We may abandon a pause if we find no region that will fit in the MMU
  42.221      // pause.
  42.222 -    abandoned = (g1_policy()->collection_set() == NULL);
  42.223 +    bool abandoned = (g1_policy()->collection_set() == NULL);
  42.224  
  42.225      // Nothing to do if we were unable to choose a collection set.
  42.226      if (!abandoned) {
  42.227 @@ -2673,12 +2618,6 @@
  42.228        _in_cset_fast_test = NULL;
  42.229        _in_cset_fast_test_base = NULL;
  42.230  
  42.231 -      if (popular_region != NULL) {
  42.232 -        // We have to wait until now, because we don't want the region to
  42.233 -        // be rescheduled for pop-evac during RS update.
  42.234 -        popular_region->set_popular_pending(false);
  42.235 -      }
  42.236 -
  42.237        release_gc_alloc_regions(false /* totally */);
  42.238  
  42.239        cleanup_surviving_young_words();
  42.240 @@ -2724,8 +2663,7 @@
  42.241      double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
  42.242      g1_policy()->record_pause_time_ms(pause_time_ms);
  42.243      GCOverheadReporter::recordSTWEnd(end_time_sec);
  42.244 -    g1_policy()->record_collection_pause_end(popular_region != NULL,
  42.245 -                                             abandoned);
  42.246 +    g1_policy()->record_collection_pause_end(abandoned);
  42.247  
  42.248      assert(regions_accounted_for(), "Region leakage.");
  42.249  
  42.250 @@ -2759,9 +2697,6 @@
  42.251  
  42.252    assert(verify_region_lists(), "Bad region lists.");
  42.253  
  42.254 -  if (reset_should_initiate_conc_mark)
  42.255 -    g1_policy()->set_should_initiate_conc_mark();
  42.256 -
  42.257    if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
  42.258      gclog_or_tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
  42.259      print_tracing_info();
  42.260 @@ -4707,7 +4642,6 @@
  42.261                                    size_t& freed_regions,
  42.262                                    UncleanRegionList* list,
  42.263                                    bool par) {
  42.264 -  assert(!hr->popular(), "should not free popular regions");
  42.265    pre_used += hr->used();
  42.266    if (hr->isHumongous()) {
  42.267      assert(hr->startsHumongous(),
  42.268 @@ -4791,12 +4725,6 @@
  42.269  
  42.270  
  42.271  void G1CollectedHeap::do_collection_pause_if_appropriate(size_t word_size) {
  42.272 -  // First do any popular regions.
  42.273 -  HeapRegion* hr;
  42.274 -  while ((hr = popular_region_to_evac()) != NULL) {
  42.275 -    evac_popular_region(hr);
  42.276 -  }
  42.277 -  // Now do heuristic pauses.
  42.278    if (g1_policy()->should_do_collection_pause(word_size)) {
  42.279      do_collection_pause();
  42.280    }
  42.281 @@ -5192,7 +5120,7 @@
  42.282  public:
  42.283    RegionCounter() : _n(0) {}
  42.284    bool doHeapRegion(HeapRegion* r) {
  42.285 -    if (r->is_empty() && !r->popular()) {
  42.286 +    if (r->is_empty()) {
  42.287        assert(!r->isHumongous(), "H regions should not be empty.");
  42.288        _n++;
  42.289      }
  42.290 @@ -5336,14 +5264,8 @@
  42.291        r->set_zero_fill_allocated();
  42.292      } else {
  42.293        assert(r->is_empty(), "tautology");
  42.294 -      if (r->popular()) {
  42.295 -        if (r->zero_fill_state() != HeapRegion::Allocated) {
  42.296 -          r->ensure_zero_filled_locked();
  42.297 -          r->set_zero_fill_allocated();
  42.298 -        }
  42.299 -      } else {
  42.300 -        _n++;
  42.301 -        switch (r->zero_fill_state()) {
  42.302 +      _n++;
  42.303 +      switch (r->zero_fill_state()) {
  42.304          case HeapRegion::NotZeroFilled:
  42.305          case HeapRegion::ZeroFilling:
  42.306            _g1->put_region_on_unclean_list_locked(r);
  42.307 @@ -5354,7 +5276,6 @@
  42.308          case HeapRegion::ZeroFilled:
  42.309            _g1->put_free_region_on_list_locked(r);
  42.310            break;
  42.311 -        }
  42.312        }
  42.313      }
  42.314      return false;
  42.315 @@ -5402,376 +5323,6 @@
  42.316    heap_region_iterate(&rs);
  42.317  }
  42.318  
  42.319 -class CountObjClosure: public ObjectClosure {
  42.320 -  size_t _n;
  42.321 -public:
  42.322 -  CountObjClosure() : _n(0) {}
  42.323 -  void do_object(oop obj) { _n++; }
  42.324 -  size_t n() { return _n; }
  42.325 -};
  42.326 -
  42.327 -size_t G1CollectedHeap::pop_object_used_objs() {
  42.328 -  size_t sum_objs = 0;
  42.329 -  for (int i = 0; i < G1NumPopularRegions; i++) {
  42.330 -    CountObjClosure cl;
  42.331 -    _hrs->at(i)->object_iterate(&cl);
  42.332 -    sum_objs += cl.n();
  42.333 -  }
  42.334 -  return sum_objs;
  42.335 -}
  42.336 -
  42.337 -size_t G1CollectedHeap::pop_object_used_bytes() {
  42.338 -  size_t sum_bytes = 0;
  42.339 -  for (int i = 0; i < G1NumPopularRegions; i++) {
  42.340 -    sum_bytes += _hrs->at(i)->used();
  42.341 -  }
  42.342 -  return sum_bytes;
  42.343 -}
  42.344 -
  42.345 -
  42.346 -static int nq = 0;
  42.347 -
  42.348 -HeapWord* G1CollectedHeap::allocate_popular_object(size_t word_size) {
  42.349 -  while (_cur_pop_hr_index < G1NumPopularRegions) {
  42.350 -    HeapRegion* cur_pop_region = _hrs->at(_cur_pop_hr_index);
  42.351 -    HeapWord* res = cur_pop_region->allocate(word_size);
  42.352 -    if (res != NULL) {
  42.353 -      // We account for popular objs directly in the used summary:
  42.354 -      _summary_bytes_used += (word_size * HeapWordSize);
  42.355 -      return res;
  42.356 -    }
  42.357 -    // Otherwise, try the next region (first making sure that we remember
  42.358 -    // the last "top" value as the "next_top_at_mark_start", so that
  42.359 -    // objects made popular during markings aren't automatically considered
  42.360 -    // live).
  42.361 -    cur_pop_region->note_end_of_copying();
  42.362 -    // Otherwise, try the next region.
  42.363 -    _cur_pop_hr_index++;
  42.364 -  }
  42.365 -  // XXX: For now !!!
  42.366 -  vm_exit_out_of_memory(word_size,
  42.367 -                        "Not enough pop obj space (To Be Fixed)");
  42.368 -  return NULL;
  42.369 -}
  42.370 -
  42.371 -class HeapRegionList: public CHeapObj {
  42.372 -  public:
  42.373 -  HeapRegion* hr;
  42.374 -  HeapRegionList* next;
  42.375 -};
  42.376 -
  42.377 -void G1CollectedHeap::schedule_popular_region_evac(HeapRegion* r) {
  42.378 -  // This might happen during parallel GC, so protect by this lock.
  42.379 -  MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
  42.380 -  // We don't schedule regions whose evacuations are already pending, or
  42.381 -  // are already being evacuated.
  42.382 -  if (!r->popular_pending() && !r->in_collection_set()) {
  42.383 -    r->set_popular_pending(true);
  42.384 -    if (G1TracePopularity) {
  42.385 -      gclog_or_tty->print_cr("Scheduling region "PTR_FORMAT" "
  42.386 -                             "["PTR_FORMAT", "PTR_FORMAT") for pop-object evacuation.",
  42.387 -                             r, r->bottom(), r->end());
  42.388 -    }
  42.389 -    HeapRegionList* hrl = new HeapRegionList;
  42.390 -    hrl->hr = r;
  42.391 -    hrl->next = _popular_regions_to_be_evacuated;
  42.392 -    _popular_regions_to_be_evacuated = hrl;
  42.393 -  }
  42.394 -}
  42.395 -
  42.396 -HeapRegion* G1CollectedHeap::popular_region_to_evac() {
  42.397 -  MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
  42.398 -  HeapRegion* res = NULL;
  42.399 -  while (_popular_regions_to_be_evacuated != NULL && res == NULL) {
  42.400 -    HeapRegionList* hrl = _popular_regions_to_be_evacuated;
  42.401 -    _popular_regions_to_be_evacuated = hrl->next;
  42.402 -    res = hrl->hr;
  42.403 -    // The G1RSPopLimit may have increased, so recheck here...
  42.404 -    if (res->rem_set()->occupied() < (size_t) G1RSPopLimit) {
  42.405 -      // Hah: don't need to schedule.
  42.406 -      if (G1TracePopularity) {
  42.407 -        gclog_or_tty->print_cr("Unscheduling region "PTR_FORMAT" "
  42.408 -                               "["PTR_FORMAT", "PTR_FORMAT") "
  42.409 -                               "for pop-object evacuation (size %d < limit %d)",
  42.410 -                               res, res->bottom(), res->end(),
  42.411 -                               res->rem_set()->occupied(), G1RSPopLimit);
  42.412 -      }
  42.413 -      res->set_popular_pending(false);
  42.414 -      res = NULL;
  42.415 -    }
  42.416 -    // We do not reset res->popular() here; if we did so, it would allow
  42.417 -    // the region to be "rescheduled" for popularity evacuation.  Instead,
  42.418 -    // this is done in the collection pause, with the world stopped.
  42.419 -    // So the invariant is that the regions in the list have the popularity
  42.420 -    // boolean set, but having the boolean set does not imply membership
  42.421 -    // on the list (though there can at most one such pop-pending region
  42.422 -    // not on the list at any time).
  42.423 -    delete hrl;
  42.424 -  }
  42.425 -  return res;
  42.426 -}
  42.427 -
  42.428 -void G1CollectedHeap::evac_popular_region(HeapRegion* hr) {
  42.429 -  while (true) {
  42.430 -    // Don't want to do a GC pause while cleanup is being completed!
  42.431 -    wait_for_cleanup_complete();
  42.432 -
  42.433 -    // Read the GC count while holding the Heap_lock
  42.434 -    int gc_count_before = SharedHeap::heap()->total_collections();
  42.435 -    g1_policy()->record_stop_world_start();
  42.436 -
  42.437 -    {
  42.438 -      MutexUnlocker mu(Heap_lock);  // give up heap lock, execute gets it back
  42.439 -      VM_G1PopRegionCollectionPause op(gc_count_before, hr);
  42.440 -      VMThread::execute(&op);
  42.441 -
  42.442 -      // If the prolog succeeded, we didn't do a GC for this.
  42.443 -      if (op.prologue_succeeded()) break;
  42.444 -    }
  42.445 -    // Otherwise we didn't.  We should recheck the size, though, since
  42.446 -    // the limit may have increased...
  42.447 -    if (hr->rem_set()->occupied() < (size_t) G1RSPopLimit) {
  42.448 -      hr->set_popular_pending(false);
  42.449 -      break;
  42.450 -    }
  42.451 -  }
  42.452 -}
  42.453 -
  42.454 -void G1CollectedHeap::atomic_inc_obj_rc(oop obj) {
  42.455 -  Atomic::inc(obj_rc_addr(obj));
  42.456 -}
  42.457 -
  42.458 -class CountRCClosure: public OopsInHeapRegionClosure {
  42.459 -  G1CollectedHeap* _g1h;
  42.460 -  bool _parallel;
  42.461 -public:
  42.462 -  CountRCClosure(G1CollectedHeap* g1h) :
  42.463 -    _g1h(g1h), _parallel(ParallelGCThreads > 0)
  42.464 -  {}
  42.465 -  void do_oop(narrowOop* p) {
  42.466 -    guarantee(false, "NYI");
  42.467 -  }
  42.468 -  void do_oop(oop* p) {
  42.469 -    oop obj = *p;
  42.470 -    assert(obj != NULL, "Precondition.");
  42.471 -    if (_parallel) {
  42.472 -      // We go sticky at the limit to avoid excess contention.
  42.473 -      // If we want to track the actual RC's further, we'll need to keep a
  42.474 -      // per-thread hash table or something for the popular objects.
  42.475 -      if (_g1h->obj_rc(obj) < G1ObjPopLimit) {
  42.476 -        _g1h->atomic_inc_obj_rc(obj);
  42.477 -      }
  42.478 -    } else {
  42.479 -      _g1h->inc_obj_rc(obj);
  42.480 -    }
  42.481 -  }
  42.482 -};
  42.483 -
  42.484 -class EvacPopObjClosure: public ObjectClosure {
  42.485 -  G1CollectedHeap* _g1h;
  42.486 -  size_t _pop_objs;
  42.487 -  size_t _max_rc;
  42.488 -public:
  42.489 -  EvacPopObjClosure(G1CollectedHeap* g1h) :
  42.490 -    _g1h(g1h), _pop_objs(0), _max_rc(0) {}
  42.491 -
  42.492 -  void do_object(oop obj) {
  42.493 -    size_t rc = _g1h->obj_rc(obj);
  42.494 -    _max_rc = MAX2(rc, _max_rc);
  42.495 -    if (rc >= (size_t) G1ObjPopLimit) {
  42.496 -      _g1h->_pop_obj_rc_at_copy.add((double)rc);
  42.497 -      size_t word_sz = obj->size();
  42.498 -      HeapWord* new_pop_loc = _g1h->allocate_popular_object(word_sz);
  42.499 -      oop new_pop_obj = (oop)new_pop_loc;
  42.500 -      Copy::aligned_disjoint_words((HeapWord*)obj, new_pop_loc, word_sz);
  42.501 -      obj->forward_to(new_pop_obj);
  42.502 -      G1ScanAndBalanceClosure scan_and_balance(_g1h);
  42.503 -      new_pop_obj->oop_iterate_backwards(&scan_and_balance);
  42.504 -      // preserve "next" mark bit if marking is in progress.
  42.505 -      if (_g1h->mark_in_progress() && !_g1h->is_obj_ill(obj)) {
  42.506 -        _g1h->concurrent_mark()->markAndGrayObjectIfNecessary(new_pop_obj);
  42.507 -      }
  42.508 -
  42.509 -      if (G1TracePopularity) {
  42.510 -        gclog_or_tty->print_cr("Found obj " PTR_FORMAT " of word size " SIZE_FORMAT
  42.511 -                               " pop (%d), move to " PTR_FORMAT,
  42.512 -                               (void*) obj, word_sz,
  42.513 -                               _g1h->obj_rc(obj), (void*) new_pop_obj);
  42.514 -      }
  42.515 -      _pop_objs++;
  42.516 -    }
  42.517 -  }
  42.518 -  size_t pop_objs() { return _pop_objs; }
  42.519 -  size_t max_rc() { return _max_rc; }
  42.520 -};
  42.521 -
  42.522 -class G1ParCountRCTask : public AbstractGangTask {
  42.523 -  G1CollectedHeap* _g1h;
  42.524 -  BitMap _bm;
  42.525 -
  42.526 -  size_t getNCards() {
  42.527 -    return (_g1h->capacity() + G1BlockOffsetSharedArray::N_bytes - 1)
  42.528 -      / G1BlockOffsetSharedArray::N_bytes;
  42.529 -  }
  42.530 -  CountRCClosure _count_rc_closure;
  42.531 -public:
  42.532 -  G1ParCountRCTask(G1CollectedHeap* g1h) :
  42.533 -    AbstractGangTask("G1 Par RC Count task"),
  42.534 -    _g1h(g1h), _bm(getNCards()), _count_rc_closure(g1h)
  42.535 -  {}
  42.536 -
  42.537 -  void work(int i) {
  42.538 -    ResourceMark rm;
  42.539 -    HandleMark   hm;
  42.540 -    _g1h->g1_rem_set()->oops_into_collection_set_do(&_count_rc_closure, i);
  42.541 -  }
  42.542 -};
  42.543 -
  42.544 -void G1CollectedHeap::popularity_pause_preamble(HeapRegion* popular_region) {
  42.545 -  // We're evacuating a single region (for popularity).
  42.546 -  if (G1TracePopularity) {
  42.547 -    gclog_or_tty->print_cr("Doing pop region pause for ["PTR_FORMAT", "PTR_FORMAT")",
  42.548 -                           popular_region->bottom(), popular_region->end());
  42.549 -  }
  42.550 -  g1_policy()->set_single_region_collection_set(popular_region);
  42.551 -  size_t max_rc;
  42.552 -  if (!compute_reference_counts_and_evac_popular(popular_region,
  42.553 -                                                 &max_rc)) {
  42.554 -    // We didn't evacuate any popular objects.
  42.555 -    // We increase the RS popularity limit, to prevent this from
  42.556 -    // happening in the future.
  42.557 -    if (G1RSPopLimit < (1 << 30)) {
  42.558 -      G1RSPopLimit *= 2;
  42.559 -    }
  42.560 -    // For now, interesting enough for a message:
  42.561 -#if 1
  42.562 -    gclog_or_tty->print_cr("In pop region pause for ["PTR_FORMAT", "PTR_FORMAT"), "
  42.563 -                           "failed to find a pop object (max = %d).",
  42.564 -                           popular_region->bottom(), popular_region->end(),
  42.565 -                           max_rc);
  42.566 -    gclog_or_tty->print_cr("Increased G1RSPopLimit to %d.", G1RSPopLimit);
  42.567 -#endif // 0
  42.568 -    // Also, we reset the collection set to NULL, to make the rest of
  42.569 -    // the collection do nothing.
  42.570 -    assert(popular_region->next_in_collection_set() == NULL,
  42.571 -           "should be single-region.");
  42.572 -    popular_region->set_in_collection_set(false);
  42.573 -    popular_region->set_popular_pending(false);
  42.574 -    g1_policy()->clear_collection_set();
  42.575 -  }
  42.576 -}
  42.577 -
  42.578 -bool G1CollectedHeap::
  42.579 -compute_reference_counts_and_evac_popular(HeapRegion* popular_region,
  42.580 -                                          size_t* max_rc) {
  42.581 -  HeapWord* rc_region_bot;
  42.582 -  HeapWord* rc_region_end;
  42.583 -
  42.584 -  // Set up the reference count region.
  42.585 -  HeapRegion* rc_region = newAllocRegion(HeapRegion::GrainWords);
  42.586 -  if (rc_region != NULL) {
  42.587 -    rc_region_bot = rc_region->bottom();
  42.588 -    rc_region_end = rc_region->end();
  42.589 -  } else {
  42.590 -    rc_region_bot = NEW_C_HEAP_ARRAY(HeapWord, HeapRegion::GrainWords);
  42.591 -    if (rc_region_bot == NULL) {
  42.592 -      vm_exit_out_of_memory(HeapRegion::GrainWords,
  42.593 -                            "No space for RC region.");
  42.594 -    }
  42.595 -    rc_region_end = rc_region_bot + HeapRegion::GrainWords;
  42.596 -  }
  42.597 -
  42.598 -  if (G1TracePopularity)
  42.599 -    gclog_or_tty->print_cr("RC region is ["PTR_FORMAT", "PTR_FORMAT")",
  42.600 -                           rc_region_bot, rc_region_end);
  42.601 -  if (rc_region_bot > popular_region->bottom()) {
  42.602 -    _rc_region_above = true;
  42.603 -    _rc_region_diff =
  42.604 -      pointer_delta(rc_region_bot, popular_region->bottom(), 1);
  42.605 -  } else {
  42.606 -    assert(rc_region_bot < popular_region->bottom(), "Can't be equal.");
  42.607 -    _rc_region_above = false;
  42.608 -    _rc_region_diff =
  42.609 -      pointer_delta(popular_region->bottom(), rc_region_bot, 1);
  42.610 -  }
  42.611 -  g1_policy()->record_pop_compute_rc_start();
  42.612 -  // Count external references.
  42.613 -  g1_rem_set()->prepare_for_oops_into_collection_set_do();
  42.614 -  if (ParallelGCThreads > 0) {
  42.615 -
  42.616 -    set_par_threads(workers()->total_workers());
  42.617 -    G1ParCountRCTask par_count_rc_task(this);
  42.618 -    workers()->run_task(&par_count_rc_task);
  42.619 -    set_par_threads(0);
  42.620 -
  42.621 -  } else {
  42.622 -    CountRCClosure count_rc_closure(this);
  42.623 -    g1_rem_set()->oops_into_collection_set_do(&count_rc_closure, 0);
  42.624 -  }
  42.625 -  g1_rem_set()->cleanup_after_oops_into_collection_set_do();
  42.626 -  g1_policy()->record_pop_compute_rc_end();
  42.627 -
  42.628 -  // Now evacuate popular objects.
  42.629 -  g1_policy()->record_pop_evac_start();
  42.630 -  EvacPopObjClosure evac_pop_obj_cl(this);
  42.631 -  popular_region->object_iterate(&evac_pop_obj_cl);
  42.632 -  *max_rc = evac_pop_obj_cl.max_rc();
  42.633 -
  42.634 -  // Make sure the last "top" value of the current popular region is copied
  42.635 -  // as the "next_top_at_mark_start", so that objects made popular during
  42.636 -  // markings aren't automatically considered live.
  42.637 -  HeapRegion* cur_pop_region = _hrs->at(_cur_pop_hr_index);
  42.638 -  cur_pop_region->note_end_of_copying();
  42.639 -
  42.640 -  if (rc_region != NULL) {
  42.641 -    free_region(rc_region);
  42.642 -  } else {
  42.643 -    FREE_C_HEAP_ARRAY(HeapWord, rc_region_bot);
  42.644 -  }
  42.645 -  g1_policy()->record_pop_evac_end();
  42.646 -
  42.647 -  return evac_pop_obj_cl.pop_objs() > 0;
  42.648 -}
  42.649 -
  42.650 -class CountPopObjInfoClosure: public HeapRegionClosure {
  42.651 -  size_t _objs;
  42.652 -  size_t _bytes;
  42.653 -
  42.654 -  class CountObjClosure: public ObjectClosure {
  42.655 -    int _n;
  42.656 -  public:
  42.657 -    CountObjClosure() : _n(0) {}
  42.658 -    void do_object(oop obj) { _n++; }
  42.659 -    size_t n() { return _n; }
  42.660 -  };
  42.661 -
  42.662 -public:
  42.663 -  CountPopObjInfoClosure() : _objs(0), _bytes(0) {}
  42.664 -  bool doHeapRegion(HeapRegion* r) {
  42.665 -    _bytes += r->used();
  42.666 -    CountObjClosure blk;
  42.667 -    r->object_iterate(&blk);
  42.668 -    _objs += blk.n();
  42.669 -    return false;
  42.670 -  }
  42.671 -  size_t objs() { return _objs; }
  42.672 -  size_t bytes() { return _bytes; }
  42.673 -};
  42.674 -
  42.675 -
  42.676 -void G1CollectedHeap::print_popularity_summary_info() const {
  42.677 -  CountPopObjInfoClosure blk;
  42.678 -  for (int i = 0; i <= _cur_pop_hr_index; i++) {
  42.679 -    blk.doHeapRegion(_hrs->at(i));
  42.680 -  }
  42.681 -  gclog_or_tty->print_cr("\nPopular objects: %d objs, %d bytes.",
  42.682 -                         blk.objs(), blk.bytes());
  42.683 -  gclog_or_tty->print_cr("   RC at copy = [avg = %5.2f, max = %5.2f, sd = %5.2f].",
  42.684 -                _pop_obj_rc_at_copy.avg(),
  42.685 -                _pop_obj_rc_at_copy.maximum(),
  42.686 -                _pop_obj_rc_at_copy.sd());
  42.687 -}
  42.688 -
  42.689  void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) {
  42.690    _refine_cte_cl->set_concurrent(concurrent);
  42.691  }
  42.692 @@ -5845,7 +5396,6 @@
  42.693  }
  42.694  
  42.695  bool G1CollectedHeap::print_region_accounting_info() {
  42.696 -  gclog_or_tty->print_cr("P regions: %d.", G1NumPopularRegions);
  42.697    gclog_or_tty->print_cr("Free regions: %d (count: %d count list %d) (clean: %d unclean: %d).",
  42.698                           free_regions(),
  42.699                           count_free_regions(), count_free_regions_list(),
    43.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Apr 01 22:31:26 2009 -0700
    43.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Apr 02 17:01:00 2009 -0700
    43.3 @@ -29,7 +29,6 @@
    43.4  
    43.5  class HeapRegion;
    43.6  class HeapRegionSeq;
    43.7 -class HeapRegionList;
    43.8  class PermanentGenerationSpec;
    43.9  class GenerationSpec;
   43.10  class OopsInHeapRegionClosure;
   43.11 @@ -143,7 +142,6 @@
   43.12    friend class VM_GenCollectForPermanentAllocation;
   43.13    friend class VM_G1CollectFull;
   43.14    friend class VM_G1IncCollectionPause;
   43.15 -  friend class VM_G1PopRegionCollectionPause;
   43.16    friend class VMStructs;
   43.17  
   43.18    // Closures used in implementation.
   43.19 @@ -253,10 +251,6 @@
   43.20    // than the current allocation region.
   43.21    size_t _summary_bytes_used;
   43.22  
   43.23 -  // Summary information about popular objects; method to print it.
   43.24 -  NumberSeq _pop_obj_rc_at_copy;
   43.25 -  void print_popularity_summary_info() const;
   43.26 -
   43.27    // This is used for a quick test on whether a reference points into
   43.28    // the collection set or not. Basically, we have an array, with one
   43.29    // byte per region, and that byte denotes whether the corresponding
   43.30 @@ -447,10 +441,8 @@
   43.31    virtual void do_collection_pause();
   43.32  
   43.33    // The guts of the incremental collection pause, executed by the vm
   43.34 -  // thread.  If "popular_region" is non-NULL, this pause should evacuate
   43.35 -  // this single region whose remembered set has gotten large, moving
   43.36 -  // any popular objects to one of the popular regions.
   43.37 -  virtual void do_collection_pause_at_safepoint(HeapRegion* popular_region);
   43.38 +  // thread.
   43.39 +  virtual void do_collection_pause_at_safepoint();
   43.40  
   43.41    // Actually do the work of evacuating the collection set.
   43.42    virtual void evacuate_collection_set();
   43.43 @@ -625,67 +617,10 @@
   43.44  
   43.45    SubTasksDone* _process_strong_tasks;
   43.46  
   43.47 -  // Allocate space to hold a popular object.  Result is guaranteed below
   43.48 -  // "popular_object_boundary()".  Note: CURRENTLY halts the system if we
   43.49 -  // run out of space to hold popular objects.
   43.50 -  HeapWord* allocate_popular_object(size_t word_size);
   43.51 -
   43.52 -  // The boundary between popular and non-popular objects.
   43.53 -  HeapWord* _popular_object_boundary;
   43.54 -
   43.55 -  HeapRegionList* _popular_regions_to_be_evacuated;
   43.56 -
   43.57 -  // Compute which objects in "single_region" are popular.  If any are,
   43.58 -  // evacuate them to a popular region, leaving behind forwarding pointers,
   43.59 -  // and select "popular_region" as the single collection set region.
   43.60 -  // Otherwise, leave the collection set null.
   43.61 -  void popularity_pause_preamble(HeapRegion* populer_region);
   43.62 -
   43.63 -  // Compute which objects in "single_region" are popular, and evacuate
   43.64 -  // them to a popular region, leaving behind forwarding pointers.
   43.65 -  // Returns "true" if at least one popular object is discovered and
   43.66 -  // evacuated.  In any case, "*max_rc" is set to the maximum reference
   43.67 -  // count of an object in the region.
   43.68 -  bool compute_reference_counts_and_evac_popular(HeapRegion* populer_region,
   43.69 -                                                 size_t* max_rc);
   43.70 -  // Subroutines used in the above.
   43.71 -  bool _rc_region_above;
   43.72 -  size_t _rc_region_diff;
   43.73 -  jint* obj_rc_addr(oop obj) {
   43.74 -    uintptr_t obj_addr = (uintptr_t)obj;
   43.75 -    if (_rc_region_above) {
   43.76 -      jint* res = (jint*)(obj_addr + _rc_region_diff);
   43.77 -      assert((uintptr_t)res > obj_addr, "RC region is above.");
   43.78 -      return res;
   43.79 -    } else {
   43.80 -      jint* res = (jint*)(obj_addr - _rc_region_diff);
   43.81 -      assert((uintptr_t)res < obj_addr, "RC region is below.");
   43.82 -      return res;
   43.83 -    }
   43.84 -  }
   43.85 -  jint obj_rc(oop obj) {
   43.86 -    return *obj_rc_addr(obj);
   43.87 -  }
   43.88 -  void inc_obj_rc(oop obj) {
   43.89 -    (*obj_rc_addr(obj))++;
   43.90 -  }
   43.91 -  void atomic_inc_obj_rc(oop obj);
   43.92 -
   43.93 -
   43.94 -  // Number of popular objects and bytes (latter is cheaper!).
   43.95 -  size_t pop_object_used_objs();
   43.96 -  size_t pop_object_used_bytes();
   43.97 -
   43.98 -  // Index of the popular region in which allocation is currently being
   43.99 -  // done.
  43.100 -  int _cur_pop_hr_index;
  43.101 -
  43.102    // List of regions which require zero filling.
  43.103    UncleanRegionList _unclean_region_list;
  43.104    bool _unclean_regions_coming;
  43.105  
  43.106 -  bool check_age_cohort_well_formed_work(int a, HeapRegion* hr);
  43.107 -
  43.108  public:
  43.109    void set_refine_cte_cl_concurrency(bool concurrent);
  43.110  
  43.111 @@ -930,14 +865,25 @@
  43.112  
  43.113    // Iterate over all the ref-containing fields of all objects, calling
  43.114    // "cl.do_oop" on each.
  43.115 -  virtual void oop_iterate(OopClosure* cl);
  43.116 +  virtual void oop_iterate(OopClosure* cl) {
  43.117 +    oop_iterate(cl, true);
  43.118 +  }
  43.119 +  void oop_iterate(OopClosure* cl, bool do_perm);
  43.120  
  43.121    // Same as above, restricted to a memory region.
  43.122 -  virtual void oop_iterate(MemRegion mr, OopClosure* cl);
  43.123 +  virtual void oop_iterate(MemRegion mr, OopClosure* cl) {
  43.124 +    oop_iterate(mr, cl, true);
  43.125 +  }
  43.126 +  void oop_iterate(MemRegion mr, OopClosure* cl, bool do_perm);
  43.127  
  43.128    // Iterate over all objects, calling "cl.do_object" on each.
  43.129 -  virtual void object_iterate(ObjectClosure* cl);
  43.130 -  virtual void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); }
  43.131 +  virtual void object_iterate(ObjectClosure* cl) {
  43.132 +    object_iterate(cl, true);
  43.133 +  }
  43.134 +  virtual void safe_object_iterate(ObjectClosure* cl) {
  43.135 +    object_iterate(cl, true);
  43.136 +  }
  43.137 +  void object_iterate(ObjectClosure* cl, bool do_perm);
  43.138  
  43.139    // Iterate over all objects allocated since the last collection, calling
  43.140    // "cl.do_object" on each.  The heap must have been initialized properly
  43.141 @@ -1066,21 +1012,6 @@
  43.142    // words.
  43.143    virtual size_t large_typearray_limit();
  43.144  
  43.145 -  // All popular objects are guaranteed to have addresses below this
  43.146 -  // boundary.
  43.147 -  HeapWord* popular_object_boundary() {
  43.148 -    return _popular_object_boundary;
  43.149 -  }
  43.150 -
  43.151 -  // Declare the region as one that should be evacuated because its
  43.152 -  // remembered set is too large.
  43.153 -  void schedule_popular_region_evac(HeapRegion* r);
  43.154 -  // If there is a popular region to evacuate it, remove it from the list
  43.155 -  // and return it.
  43.156 -  HeapRegion* popular_region_to_evac();
  43.157 -  // Evacuate the given popular region.
  43.158 -  void evac_popular_region(HeapRegion* r);
  43.159 -
  43.160    // Returns "true" iff the given word_size is "very large".
  43.161    static bool isHumongous(size_t word_size) {
  43.162      return word_size >= VeryLargeInWords;
    44.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Apr 01 22:31:26 2009 -0700
    44.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Apr 02 17:01:00 2009 -0700
    44.3 @@ -91,10 +91,8 @@
    44.4  
    44.5    _all_mod_union_times_ms(new NumberSeq()),
    44.6  
    44.7 -  _non_pop_summary(new NonPopSummary()),
    44.8 -  _pop_summary(new PopSummary()),
    44.9 -  _non_pop_abandoned_summary(new NonPopAbandonedSummary()),
   44.10 -  _pop_abandoned_summary(new PopAbandonedSummary()),
   44.11 +  _summary(new Summary()),
   44.12 +  _abandoned_summary(new AbandonedSummary()),
   44.13  
   44.14    _cur_clear_ct_time_ms(0.0),
   44.15  
   44.16 @@ -109,9 +107,6 @@
   44.17    _cur_aux_times_ms(new double[_aux_num]),
   44.18    _cur_aux_times_set(new bool[_aux_num]),
   44.19  
   44.20 -  _pop_compute_rc_start(0.0),
   44.21 -  _pop_evac_start(0.0),
   44.22 -
   44.23    _concurrent_mark_init_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
   44.24    _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
   44.25    _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
   44.26 @@ -224,16 +219,6 @@
   44.27  
   44.28    _par_last_termination_times_ms = new double[_parallel_gc_threads];
   44.29  
   44.30 -  // we store the data from the first pass during popularity pauses
   44.31 -  _pop_par_last_update_rs_start_times_ms = new double[_parallel_gc_threads];
   44.32 -  _pop_par_last_update_rs_times_ms = new double[_parallel_gc_threads];
   44.33 -  _pop_par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];
   44.34 -
   44.35 -  _pop_par_last_scan_rs_start_times_ms = new double[_parallel_gc_threads];
   44.36 -  _pop_par_last_scan_rs_times_ms = new double[_parallel_gc_threads];
   44.37 -
   44.38 -  _pop_par_last_closure_app_times_ms = new double[_parallel_gc_threads];
   44.39 -
   44.40    // start conservatively
   44.41    _expensive_region_limit_ms = 0.5 * (double) G1MaxPauseTimeMS;
   44.42  
   44.43 @@ -1047,23 +1032,6 @@
   44.44    calculate_young_list_target_config();
   44.45   }
   44.46  
   44.47 -void G1CollectorPolicy::record_pop_compute_rc_start() {
   44.48 -  _pop_compute_rc_start = os::elapsedTime();
   44.49 -}
   44.50 -void G1CollectorPolicy::record_pop_compute_rc_end() {
   44.51 -  double ms = (os::elapsedTime() - _pop_compute_rc_start)*1000.0;
   44.52 -  _cur_popular_compute_rc_time_ms = ms;
   44.53 -  _pop_compute_rc_start = 0.0;
   44.54 -}
   44.55 -void G1CollectorPolicy::record_pop_evac_start() {
   44.56 -  _pop_evac_start = os::elapsedTime();
   44.57 -}
   44.58 -void G1CollectorPolicy::record_pop_evac_end() {
   44.59 -  double ms = (os::elapsedTime() - _pop_evac_start)*1000.0;
   44.60 -  _cur_popular_evac_time_ms = ms;
   44.61 -  _pop_evac_start = 0.0;
   44.62 -}
   44.63 -
   44.64  void G1CollectorPolicy::record_before_bytes(size_t bytes) {
   44.65    _bytes_in_to_space_before_gc += bytes;
   44.66  }
   44.67 @@ -1120,13 +1088,6 @@
   44.68      _par_last_scan_new_refs_times_ms[i] = -666.0;
   44.69      _par_last_obj_copy_times_ms[i] = -666.0;
   44.70      _par_last_termination_times_ms[i] = -666.0;
   44.71 -
   44.72 -    _pop_par_last_update_rs_start_times_ms[i] = -666.0;
   44.73 -    _pop_par_last_update_rs_times_ms[i] = -666.0;
   44.74 -    _pop_par_last_update_rs_processed_buffers[i] = -666.0;
   44.75 -    _pop_par_last_scan_rs_start_times_ms[i] = -666.0;
   44.76 -    _pop_par_last_scan_rs_times_ms[i] = -666.0;
   44.77 -    _pop_par_last_closure_app_times_ms[i] = -666.0;
   44.78    }
   44.79  #endif
   44.80  
   44.81 @@ -1185,25 +1146,6 @@
   44.82    guarantee( false, "we should never reach here" );
   44.83  }
   44.84  
   44.85 -void G1CollectorPolicy::record_popular_pause_preamble_start() {
   44.86 -  _cur_popular_preamble_start_ms = os::elapsedTime() * 1000.0;
   44.87 -}
   44.88 -
   44.89 -void G1CollectorPolicy::record_popular_pause_preamble_end() {
   44.90 -  _cur_popular_preamble_time_ms =
   44.91 -    (os::elapsedTime() * 1000.0) - _cur_popular_preamble_start_ms;
   44.92 -
   44.93 -  // copy the recorded statistics of the first pass to temporary arrays
   44.94 -  for (int i = 0; i < _parallel_gc_threads; ++i) {
   44.95 -    _pop_par_last_update_rs_start_times_ms[i] = _par_last_update_rs_start_times_ms[i];
   44.96 -    _pop_par_last_update_rs_times_ms[i] = _par_last_update_rs_times_ms[i];
   44.97 -    _pop_par_last_update_rs_processed_buffers[i] = _par_last_update_rs_processed_buffers[i];
   44.98 -    _pop_par_last_scan_rs_start_times_ms[i] = _par_last_scan_rs_start_times_ms[i];
   44.99 -    _pop_par_last_scan_rs_times_ms[i] = _par_last_scan_rs_times_ms[i];
  44.100 -    _pop_par_last_closure_app_times_ms[i] = _par_last_obj_copy_times_ms[i];
  44.101 -  }
  44.102 -}
  44.103 -
  44.104  void G1CollectorPolicy::record_mark_closure_time(double mark_closure_time_ms) {
  44.105    _mark_closure_time_ms = mark_closure_time_ms;
  44.106  }
  44.107 @@ -1465,8 +1407,7 @@
  44.108  // Anything below that is considered to be zero
  44.109  #define MIN_TIMER_GRANULARITY 0.0000001
  44.110  
  44.111 -void G1CollectorPolicy::record_collection_pause_end(bool popular,
  44.112 -                                                    bool abandoned) {
  44.113 +void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
  44.114    double end_time_sec = os::elapsedTime();
  44.115    double elapsed_ms = _last_pause_time_ms;
  44.116    bool parallel = ParallelGCThreads > 0;
  44.117 @@ -1587,42 +1528,10 @@
  44.118    }
  44.119  
  44.120    PauseSummary* summary;
  44.121 -  if (!abandoned && !popular)
  44.122 -    summary = _non_pop_summary;
  44.123 -  else if (!abandoned && popular)
  44.124 -    summary = _pop_summary;
  44.125 -  else if (abandoned && !popular)
  44.126 -    summary = _non_pop_abandoned_summary;
  44.127 -  else if (abandoned && popular)
  44.128 -    summary = _pop_abandoned_summary;
  44.129 -  else
  44.130 -    guarantee(false, "should not get here!");
  44.131 -
  44.132 -  double pop_update_rs_time;
  44.133 -  double pop_update_rs_processed_buffers;
  44.134 -  double pop_scan_rs_time;
  44.135 -  double pop_closure_app_time;
  44.136 -  double pop_other_time;
  44.137 -
  44.138 -  if (popular) {
  44.139 -    PopPreambleSummary* preamble_summary = summary->pop_preamble_summary();
  44.140 -    guarantee(preamble_summary != NULL, "should not be null!");
  44.141 -
  44.142 -    pop_update_rs_time = avg_value(_pop_par_last_update_rs_times_ms);
  44.143 -    pop_update_rs_processed_buffers =
  44.144 -      sum_of_values(_pop_par_last_update_rs_processed_buffers);
  44.145 -    pop_scan_rs_time = avg_value(_pop_par_last_scan_rs_times_ms);
  44.146 -    pop_closure_app_time = avg_value(_pop_par_last_closure_app_times_ms);
  44.147 -    pop_other_time = _cur_popular_preamble_time_ms -
  44.148 -      (pop_update_rs_time + pop_scan_rs_time + pop_closure_app_time +
  44.149 -       _cur_popular_evac_time_ms);
  44.150 -
  44.151 -    preamble_summary->record_pop_preamble_time_ms(_cur_popular_preamble_time_ms);
  44.152 -    preamble_summary->record_pop_update_rs_time_ms(pop_update_rs_time);
  44.153 -    preamble_summary->record_pop_scan_rs_time_ms(pop_scan_rs_time);
  44.154 -    preamble_summary->record_pop_closure_app_time_ms(pop_closure_app_time);
  44.155 -    preamble_summary->record_pop_evacuation_time_ms(_cur_popular_evac_time_ms);
  44.156 -    preamble_summary->record_pop_other_time_ms(pop_other_time);
  44.157 +  if (abandoned) {
  44.158 +    summary = _abandoned_summary;
  44.159 +  } else {
  44.160 +    summary = _summary;
  44.161    }
  44.162  
  44.163    double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
  44.164 @@ -1694,8 +1603,6 @@
  44.165    }
  44.166  
  44.167    double other_time_ms = elapsed_ms;
  44.168 -  if (popular)
  44.169 -    other_time_ms -= _cur_popular_preamble_time_ms;
  44.170  
  44.171    if (!abandoned) {
  44.172      if (_satb_drain_time_set)
  44.173 @@ -1712,41 +1619,24 @@
  44.174  
  44.175    if (PrintGCDetails) {
  44.176      gclog_or_tty->print_cr("%s%s, %1.8lf secs]",
  44.177 -                           (popular && !abandoned) ? " (popular)" :
  44.178 -                           (!popular && abandoned) ? " (abandoned)" :
  44.179 -                           (popular && abandoned) ? " (popular/abandoned)" : "",
  44.180 +                           abandoned ? " (abandoned)" : "",
  44.181                             (last_pause_included_initial_mark) ? " (initial-mark)" : "",
  44.182                             elapsed_ms / 1000.0);
  44.183  
  44.184      if (!abandoned) {
  44.185 -      if (_satb_drain_time_set)
  44.186 +      if (_satb_drain_time_set) {
  44.187          print_stats(1, "SATB Drain Time", _cur_satb_drain_time_ms);
  44.188 -      if (_last_satb_drain_processed_buffers >= 0)
  44.189 +      }
  44.190 +      if (_last_satb_drain_processed_buffers >= 0) {
  44.191          print_stats(2, "Processed Buffers", _last_satb_drain_processed_buffers);
  44.192 -    }
  44.193 -    if (popular)
  44.194 -      print_stats(1, "Popularity Preamble", _cur_popular_preamble_time_ms);
  44.195 -    if (parallel) {
  44.196 -      if (popular) {
  44.197 -        print_par_stats(2, "Update RS (Start)", _pop_par_last_update_rs_start_times_ms, false);
  44.198 -        print_par_stats(2, "Update RS", _pop_par_last_update_rs_times_ms);
  44.199 +      }
  44.200 +      if (parallel) {
  44.201 +        print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
  44.202 +        print_par_stats(2, "Update RS (Start)", _par_last_update_rs_start_times_ms, false);
  44.203 +        print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
  44.204          if (G1RSBarrierUseQueue)
  44.205            print_par_buffers(3, "Processed Buffers",
  44.206 -                            _pop_par_last_update_rs_processed_buffers, true);
  44.207 -        print_par_stats(2, "Scan RS", _pop_par_last_scan_rs_times_ms);
  44.208 -        print_par_stats(2, "Closure app", _pop_par_last_closure_app_times_ms);
  44.209 -        print_stats(2, "Evacuation", _cur_popular_evac_time_ms);
  44.210 -        print_stats(2, "Other", pop_other_time);
  44.211 -      }
  44.212 -      if (!abandoned) {
  44.213 -        print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
  44.214 -        if (!popular) {
  44.215 -          print_par_stats(2, "Update RS (Start)", _par_last_update_rs_start_times_ms, false);
  44.216 -          print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
  44.217 -          if (G1RSBarrierUseQueue)
  44.218 -            print_par_buffers(3, "Processed Buffers",
  44.219 -                              _par_last_update_rs_processed_buffers, true);
  44.220 -        }
  44.221 +                            _par_last_update_rs_processed_buffers, true);
  44.222          print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
  44.223          print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms);
  44.224          print_par_stats(2, "Scan-Only Scanning", _par_last_scan_only_times_ms);
  44.225 @@ -1757,25 +1647,11 @@
  44.226          print_par_stats(2, "Termination", _par_last_termination_times_ms);
  44.227          print_stats(2, "Other", parallel_other_time);
  44.228          print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
  44.229 -      }
  44.230 -    } else {
  44.231 -      if (popular) {
  44.232 -        print_stats(2, "Update RS", pop_update_rs_time);
  44.233 +      } else {
  44.234 +        print_stats(1, "Update RS", update_rs_time);
  44.235          if (G1RSBarrierUseQueue)
  44.236 -          print_stats(3, "Processed Buffers",
  44.237 -                      (int)pop_update_rs_processed_buffers);
  44.238 -        print_stats(2, "Scan RS", pop_scan_rs_time);
  44.239 -        print_stats(2, "Closure App", pop_closure_app_time);
  44.240 -        print_stats(2, "Evacuation", _cur_popular_evac_time_ms);
  44.241 -        print_stats(2, "Other", pop_other_time);
  44.242 -      }
  44.243 -      if (!abandoned) {
  44.244 -        if (!popular) {
  44.245 -          print_stats(1, "Update RS", update_rs_time);
  44.246 -          if (G1RSBarrierUseQueue)
  44.247 -            print_stats(2, "Processed Buffers",
  44.248 -                        (int)update_rs_processed_buffers);
  44.249 -        }
  44.250 +          print_stats(2, "Processed Buffers",
  44.251 +                      (int)update_rs_processed_buffers);
  44.252          print_stats(1, "Ext Root Scanning", ext_root_scan_time);
  44.253          print_stats(1, "Mark Stack Scanning", mark_stack_scan_time);
  44.254          print_stats(1, "Scan-Only Scanning", scan_only_time);
  44.255 @@ -1855,7 +1731,7 @@
  44.256  
  44.257    // <NEW PREDICTION>
  44.258  
  44.259 -  if (!popular && update_stats) {
  44.260 +  if (update_stats) {
  44.261      double pause_time_ms = elapsed_ms;
  44.262  
  44.263      size_t diff = 0;
  44.264 @@ -2454,36 +2330,8 @@
  44.265  void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
  44.266    bool parallel = ParallelGCThreads > 0;
  44.267    MainBodySummary*    body_summary = summary->main_body_summary();
  44.268 -  PopPreambleSummary* preamble_summary = summary->pop_preamble_summary();
  44.269 -
  44.270    if (summary->get_total_seq()->num() > 0) {
  44.271 -    print_summary_sd(0,
  44.272 -                     (preamble_summary == NULL) ? "Non-Popular Pauses" :
  44.273 -                     "Popular Pauses",
  44.274 -                     summary->get_total_seq());
  44.275 -    if (preamble_summary != NULL) {
  44.276 -      print_summary(1, "Popularity Preamble",
  44.277 -                    preamble_summary->get_pop_preamble_seq());
  44.278 -      print_summary(2, "Update RS", preamble_summary->get_pop_update_rs_seq());
  44.279 -      print_summary(2, "Scan RS", preamble_summary->get_pop_scan_rs_seq());
  44.280 -      print_summary(2, "Closure App",
  44.281 -                    preamble_summary->get_pop_closure_app_seq());
  44.282 -      print_summary(2, "Evacuation",
  44.283 -                    preamble_summary->get_pop_evacuation_seq());
  44.284 -      print_summary(2, "Other", preamble_summary->get_pop_other_seq());
  44.285 -      {
  44.286 -        NumberSeq* other_parts[] = {
  44.287 -          preamble_summary->get_pop_update_rs_seq(),
  44.288 -          preamble_summary->get_pop_scan_rs_seq(),
  44.289 -          preamble_summary->get_pop_closure_app_seq(),
  44.290 -          preamble_summary->get_pop_evacuation_seq()
  44.291 -        };
  44.292 -        NumberSeq calc_other_times_ms(preamble_summary->get_pop_preamble_seq(),
  44.293 -                                      4, other_parts);
  44.294 -        check_other_times(2, preamble_summary->get_pop_other_seq(),
  44.295 -                          &calc_other_times_ms);
  44.296 -      }
  44.297 -    }
  44.298 +    print_summary_sd(0, "Evacuation Pauses", summary->get_total_seq());
  44.299      if (body_summary != NULL) {
  44.300        print_summary(1, "SATB Drain", body_summary->get_satb_drain_seq());
  44.301        if (parallel) {
  44.302 @@ -2537,19 +2385,15 @@
  44.303            // parallel
  44.304            NumberSeq* other_parts[] = {
  44.305              body_summary->get_satb_drain_seq(),
  44.306 -            (preamble_summary == NULL) ? NULL :
  44.307 -              preamble_summary->get_pop_preamble_seq(),
  44.308              body_summary->get_parallel_seq(),
  44.309              body_summary->get_clear_ct_seq()
  44.310            };
  44.311 -          calc_other_times_ms = NumberSeq (summary->get_total_seq(),
  44.312 -                                          4, other_parts);
  44.313 +          calc_other_times_ms = NumberSeq(summary->get_total_seq(),
  44.314 +                                          3, other_parts);
  44.315          } else {
  44.316            // serial
  44.317            NumberSeq* other_parts[] = {
  44.318              body_summary->get_satb_drain_seq(),
  44.319 -            (preamble_summary == NULL) ? NULL :
  44.320 -              preamble_summary->get_pop_preamble_seq(),
  44.321              body_summary->get_update_rs_seq(),
  44.322              body_summary->get_ext_root_scan_seq(),
  44.323              body_summary->get_mark_stack_scan_seq(),
  44.324 @@ -2558,16 +2402,11 @@
  44.325              body_summary->get_obj_copy_seq()
  44.326            };
  44.327            calc_other_times_ms = NumberSeq(summary->get_total_seq(),
  44.328 -                                          8, other_parts);
  44.329 +                                          7, other_parts);
  44.330          }
  44.331        } else {
  44.332          // abandoned
  44.333 -        NumberSeq* other_parts[] = {
  44.334 -          (preamble_summary == NULL) ? NULL :
  44.335 -            preamble_summary->get_pop_preamble_seq()
  44.336 -        };
  44.337 -        calc_other_times_ms = NumberSeq(summary->get_total_seq(),
  44.338 -                                        1, other_parts);
  44.339 +        calc_other_times_ms = NumberSeq();
  44.340        }
  44.341        check_other_times(1,  summary->get_other_seq(), &calc_other_times_ms);
  44.342      }
  44.343 @@ -2579,18 +2418,12 @@
  44.344  }
  44.345  
  44.346  void
  44.347 -G1CollectorPolicy::print_abandoned_summary(PauseSummary* non_pop_summary,
  44.348 -                                           PauseSummary* pop_summary) const {
  44.349 +G1CollectorPolicy::print_abandoned_summary(PauseSummary* summary) const {
  44.350    bool printed = false;
  44.351 -  if (non_pop_summary->get_total_seq()->num() > 0) {
  44.352 +  if (summary->get_total_seq()->num() > 0) {
  44.353      printed = true;
  44.354 -    print_summary(non_pop_summary);
  44.355 +    print_summary(summary);
  44.356    }
  44.357 -  if (pop_summary->get_total_seq()->num() > 0) {
  44.358 -    printed = true;
  44.359 -    print_summary(pop_summary);
  44.360 -  }
  44.361 -
  44.362    if (!printed) {
  44.363      print_indent(0);
  44.364      gclog_or_tty->print_cr("none");
  44.365 @@ -2608,15 +2441,11 @@
  44.366      gclog_or_tty->print_cr("   Partial Young GC Pauses: %8d", _partial_young_pause_num);
  44.367      gclog_or_tty->print_cr("");
  44.368  
  44.369 -    gclog_or_tty->print_cr("NON-POPULAR PAUSES");
  44.370 -    print_summary(_non_pop_summary);
  44.371 -
  44.372 -    gclog_or_tty->print_cr("POPULAR PAUSES");
  44.373 -    print_summary(_pop_summary);
  44.374 +    gclog_or_tty->print_cr("EVACUATION PAUSES");
  44.375 +    print_summary(_summary);
  44.376  
  44.377      gclog_or_tty->print_cr("ABANDONED PAUSES");
  44.378 -    print_abandoned_summary(_non_pop_abandoned_summary,
  44.379 -                            _pop_abandoned_summary);
  44.380 +    print_abandoned_summary(_abandoned_summary);
  44.381  
  44.382      gclog_or_tty->print_cr("MISC");
  44.383      print_summary_sd(0, "Stop World", _all_stop_world_times_ms);
  44.384 @@ -2702,14 +2531,6 @@
  44.385    _conc_refine_enabled++;
  44.386  }
  44.387  
  44.388 -void G1CollectorPolicy::set_single_region_collection_set(HeapRegion* hr) {
  44.389 -  assert(collection_set() == NULL, "Must be no current CS.");
  44.390 -  _collection_set_size = 0;
  44.391 -  _collection_set_bytes_used_before = 0;
  44.392 -  add_to_collection_set(hr);
  44.393 -  count_CS_bytes_used();
  44.394 -}
  44.395 -
  44.396  bool
  44.397  G1CollectorPolicy::should_add_next_region_to_young_list() {
  44.398    assert(in_young_gc_mode(), "should be in young GC mode");
  44.399 @@ -2787,15 +2608,6 @@
  44.400    }
  44.401  }
  44.402  
  44.403 -
  44.404 -void
  44.405 -G1CollectorPolicy_BestRegionsFirst::
  44.406 -set_single_region_collection_set(HeapRegion* hr) {
  44.407 -  G1CollectorPolicy::set_single_region_collection_set(hr);
  44.408 -  _collectionSetChooser->removeRegion(hr);
  44.409 -}
  44.410 -
  44.411 -
  44.412  bool
  44.413  G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t
  44.414                                                                 word_size) {
  44.415 @@ -3061,19 +2873,13 @@
  44.416  
  44.417  void
  44.418  G1CollectorPolicy_BestRegionsFirst::
  44.419 -choose_collection_set(HeapRegion* pop_region) {
  44.420 +choose_collection_set() {
  44.421    double non_young_start_time_sec;
  44.422    start_recording_regions();
  44.423  
  44.424 -  if (pop_region != NULL) {
  44.425 -    _target_pause_time_ms = (double) G1MaxPauseTimeMS;
  44.426 -  } else {
  44.427 -    guarantee(_target_pause_time_ms > -1.0,
  44.428 -              "_target_pause_time_ms should have been set!");
  44.429 -  }
  44.430 -
  44.431 -  // pop region is either null (and so is CS), or else it *is* the CS.
  44.432 -  assert(_collection_set == pop_region, "Precondition");
  44.433 +  guarantee(_target_pause_time_ms > -1.0,
  44.434 +            "_target_pause_time_ms should have been set!");
  44.435 +  assert(_collection_set == NULL, "Precondition");
  44.436  
  44.437    double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
  44.438    double predicted_pause_time_ms = base_time_ms;
  44.439 @@ -3100,15 +2906,13 @@
  44.440    size_t expansion_bytes =
  44.441      _g1->expansion_regions() * HeapRegion::GrainBytes;
  44.442  
  44.443 -  if (pop_region == NULL) {
  44.444 -    _collection_set_bytes_used_before = 0;
  44.445 -    _collection_set_size = 0;
  44.446 -  }
  44.447 +  _collection_set_bytes_used_before = 0;
  44.448 +  _collection_set_size = 0;
  44.449  
  44.450    // Adjust for expansion and slop.
  44.451    max_live_bytes = max_live_bytes + expansion_bytes;
  44.452  
  44.453 -  assert(pop_region != NULL || _g1->regions_accounted_for(), "Region leakage!");
  44.454 +  assert(_g1->regions_accounted_for(), "Region leakage!");
  44.455  
  44.456    HeapRegion* hr;
  44.457    if (in_young_gc_mode()) {
  44.458 @@ -3135,14 +2939,9 @@
  44.459        double predicted_time_ms = predict_region_elapsed_time_ms(hr, true);
  44.460        time_remaining_ms -= predicted_time_ms;
  44.461        predicted_pause_time_ms += predicted_time_ms;
  44.462 -      if (hr == pop_region) {
  44.463 -        // The popular region was young.  Skip over it.
  44.464 -        assert(hr->in_collection_set(), "It's the pop region.");
  44.465 -      } else {
  44.466 -        assert(!hr->in_collection_set(), "It's not the pop region.");
  44.467 -        add_to_collection_set(hr);
  44.468 -        record_cset_region(hr, true);
  44.469 -      }
  44.470 +      assert(!hr->in_collection_set(), "invariant");
  44.471 +      add_to_collection_set(hr);
  44.472 +      record_cset_region(hr, true);
  44.473        max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes);
  44.474        if (G1PolicyVerbose > 0) {
  44.475          gclog_or_tty->print_cr("  Added [" PTR_FORMAT ", " PTR_FORMAT") to CS.",
  44.476 @@ -3165,10 +2964,6 @@
  44.477        // don't bother adding more regions...
  44.478        goto choose_collection_set_end;
  44.479      }
  44.480 -  } else if (pop_region != NULL) {
  44.481 -    // We're not in young mode, and we chose a popular region; don't choose
  44.482 -    // any more.
  44.483 -    return;
  44.484    }
  44.485  
  44.486    if (!in_young_gc_mode() || !full_young_gcs()) {
  44.487 @@ -3178,7 +2973,7 @@
  44.488      do {
  44.489        hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
  44.490                                                        avg_prediction);
  44.491 -      if (hr != NULL && !hr->popular()) {
  44.492 +      if (hr != NULL) {
  44.493          double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
  44.494          time_remaining_ms -= predicted_time_ms;
  44.495          predicted_pause_time_ms += predicted_time_ms;
  44.496 @@ -3225,8 +3020,8 @@
  44.497  }
  44.498  
  44.499  void G1CollectorPolicy_BestRegionsFirst::
  44.500 -record_collection_pause_end(bool popular, bool abandoned) {
  44.501 -  G1CollectorPolicy::record_collection_pause_end(popular, abandoned);
  44.502 +record_collection_pause_end(bool abandoned) {
  44.503 +  G1CollectorPolicy::record_collection_pause_end(abandoned);
  44.504    assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
  44.505  }
  44.506  
    45.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Wed Apr 01 22:31:26 2009 -0700
    45.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Thu Apr 02 17:01:00 2009 -0700
    45.3 @@ -47,7 +47,6 @@
    45.4    }
    45.5  
    45.6  class MainBodySummary;
    45.7 -class PopPreambleSummary;
    45.8  
    45.9  class PauseSummary: public CHeapObj {
   45.10    define_num_seq(total)
   45.11 @@ -55,7 +54,6 @@
   45.12  
   45.13  public:
   45.14    virtual MainBodySummary*    main_body_summary()    { return NULL; }
   45.15 -  virtual PopPreambleSummary* pop_preamble_summary() { return NULL; }
   45.16  };
   45.17  
   45.18  class MainBodySummary: public CHeapObj {
   45.19 @@ -75,36 +73,13 @@
   45.20    define_num_seq(clear_ct)  // parallel only
   45.21  };
   45.22  
   45.23 -class PopPreambleSummary: public CHeapObj {
   45.24 -  define_num_seq(pop_preamble)
   45.25 -    define_num_seq(pop_update_rs)
   45.26 -    define_num_seq(pop_scan_rs)
   45.27 -    define_num_seq(pop_closure_app)
   45.28 -    define_num_seq(pop_evacuation)
   45.29 -    define_num_seq(pop_other)
   45.30 -};
   45.31 -
   45.32 -class NonPopSummary: public PauseSummary,
   45.33 -                     public MainBodySummary {
   45.34 +class Summary: public PauseSummary,
   45.35 +               public MainBodySummary {
   45.36  public:
   45.37    virtual MainBodySummary*    main_body_summary()    { return this; }
   45.38  };
   45.39  
   45.40 -class PopSummary: public PauseSummary,
   45.41 -                  public MainBodySummary,
   45.42 -                  public PopPreambleSummary {
   45.43 -public:
   45.44 -  virtual MainBodySummary*    main_body_summary()    { return this; }
   45.45 -  virtual PopPreambleSummary* pop_preamble_summary() { return this; }
   45.46 -};
   45.47 -
   45.48 -class NonPopAbandonedSummary: public PauseSummary {
   45.49 -};
   45.50 -
   45.51 -class PopAbandonedSummary: public PauseSummary,
   45.52 -                           public PopPreambleSummary {
   45.53 -public:
   45.54 -  virtual PopPreambleSummary* pop_preamble_summary() { return this; }
   45.55 +class AbandonedSummary: public PauseSummary {
   45.56  };
   45.57  
   45.58  class G1CollectorPolicy: public CollectorPolicy {
   45.59 @@ -146,10 +121,6 @@
   45.60    double _cur_satb_drain_time_ms;
   45.61    double _cur_clear_ct_time_ms;
   45.62    bool   _satb_drain_time_set;
   45.63 -  double _cur_popular_preamble_start_ms;
   45.64 -  double _cur_popular_preamble_time_ms;
   45.65 -  double _cur_popular_compute_rc_time_ms;
   45.66 -  double _cur_popular_evac_time_ms;
   45.67  
   45.68    double _cur_CH_strong_roots_end_sec;
   45.69    double _cur_CH_strong_roots_dur_ms;
   45.70 @@ -173,10 +144,8 @@
   45.71    TruncatedSeq* _concurrent_mark_remark_times_ms;
   45.72    TruncatedSeq* _concurrent_mark_cleanup_times_ms;
   45.73  
   45.74 -  NonPopSummary*           _non_pop_summary;
   45.75 -  PopSummary*              _pop_summary;
   45.76 -  NonPopAbandonedSummary*  _non_pop_abandoned_summary;
   45.77 -  PopAbandonedSummary*     _pop_abandoned_summary;
   45.78 +  Summary*           _summary;
   45.79 +  AbandonedSummary*  _abandoned_summary;
   45.80  
   45.81    NumberSeq* _all_pause_times_ms;
   45.82    NumberSeq* _all_full_gc_times_ms;
   45.83 @@ -210,18 +179,6 @@
   45.84    double* _par_last_obj_copy_times_ms;
   45.85    double* _par_last_termination_times_ms;
   45.86  
   45.87 -  // there are two pases during popular pauses, so we need to store
   45.88 -  // somewhere the results of the first pass
   45.89 -  double* _pop_par_last_update_rs_start_times_ms;
   45.90 -  double* _pop_par_last_update_rs_times_ms;
   45.91 -  double* _pop_par_last_update_rs_processed_buffers;
   45.92 -  double* _pop_par_last_scan_rs_start_times_ms;
   45.93 -  double* _pop_par_last_scan_rs_times_ms;
   45.94 -  double* _pop_par_last_closure_app_times_ms;
   45.95 -
   45.96 -  double _pop_compute_rc_start;
   45.97 -  double _pop_evac_start;
   45.98 -
   45.99    // indicates that we are in young GC mode
  45.100    bool _in_young_gc_mode;
  45.101  
  45.102 @@ -634,8 +591,7 @@
  45.103                           NumberSeq* calc_other_times_ms) const;
  45.104  
  45.105    void print_summary (PauseSummary* stats) const;
  45.106 -  void print_abandoned_summary(PauseSummary* non_pop_summary,
  45.107 -                               PauseSummary* pop_summary) const;
  45.108 +  void print_abandoned_summary(PauseSummary* summary) const;
  45.109  
  45.110    void print_summary (int level, const char* str, NumberSeq* seq) const;
  45.111    void print_summary_sd (int level, const char* str, NumberSeq* seq) const;
  45.112 @@ -856,9 +812,6 @@
  45.113    virtual void record_collection_pause_start(double start_time_sec,
  45.114                                               size_t start_used);
  45.115  
  45.116 -  virtual void record_popular_pause_preamble_start();
  45.117 -  virtual void record_popular_pause_preamble_end();
  45.118 -
  45.119    // Must currently be called while the world is stopped.
  45.120    virtual void record_concurrent_mark_init_start();
  45.121    virtual void record_concurrent_mark_init_end();
  45.122 @@ -881,7 +834,7 @@
  45.123    virtual void record_collection_pause_end_CH_strong_roots();
  45.124    virtual void record_collection_pause_end_G1_strong_roots();
  45.125  
  45.126 -  virtual void record_collection_pause_end(bool popular, bool abandoned);
  45.127 +  virtual void record_collection_pause_end(bool abandoned);
  45.128  
  45.129    // Record the fact that a full collection occurred.
  45.130    virtual void record_full_collection_start();
  45.131 @@ -990,12 +943,6 @@
  45.132      _cur_aux_times_ms[i] += ms;
  45.133    }
  45.134  
  45.135 -  void record_pop_compute_rc_start();
  45.136 -  void record_pop_compute_rc_end();
  45.137 -
  45.138 -  void record_pop_evac_start();
  45.139 -  void record_pop_evac_end();
  45.140 -
  45.141    // Record the fact that "bytes" bytes allocated in a region.
  45.142    void record_before_bytes(size_t bytes);
  45.143    void record_after_bytes(size_t bytes);
  45.144 @@ -1008,9 +955,7 @@
  45.145    // Choose a new collection set.  Marks the chosen regions as being
  45.146    // "in_collection_set", and links them together.  The head and number of
  45.147    // the collection set are available via access methods.
  45.148 -  // If "pop_region" is non-NULL, it is a popular region that has already
  45.149 -  // been added to the collection set.
  45.150 -  virtual void choose_collection_set(HeapRegion* pop_region = NULL) = 0;
  45.151 +  virtual void choose_collection_set() = 0;
  45.152  
  45.153    void clear_collection_set() { _collection_set = NULL; }
  45.154  
  45.155 @@ -1018,9 +963,6 @@
  45.156    // current collection set.
  45.157    HeapRegion* collection_set() { return _collection_set; }
  45.158  
  45.159 -  // Sets the collection set to the given single region.
  45.160 -  virtual void set_single_region_collection_set(HeapRegion* hr);
  45.161 -
  45.162    // The number of elements in the current collection set.
  45.163    size_t collection_set_size() { return _collection_set_size; }
  45.164  
  45.165 @@ -1203,7 +1145,7 @@
  45.166    // If the estimated is less then desirable, resize if possible.
  45.167    void expand_if_possible(size_t numRegions);
  45.168  
  45.169 -  virtual void choose_collection_set(HeapRegion* pop_region = NULL);
  45.170 +  virtual void choose_collection_set();
  45.171    virtual void record_collection_pause_start(double start_time_sec,
  45.172                                               size_t start_used);
  45.173    virtual void record_concurrent_mark_cleanup_end(size_t freed_bytes,
  45.174 @@ -1214,9 +1156,8 @@
  45.175    G1CollectorPolicy_BestRegionsFirst() {
  45.176      _collectionSetChooser = new CollectionSetChooser();
  45.177    }
  45.178 -  void record_collection_pause_end(bool popular, bool abandoned);
  45.179 +  void record_collection_pause_end(bool abandoned);
  45.180    bool should_do_collection_pause(size_t word_size);
  45.181 -  virtual void set_single_region_collection_set(HeapRegion* hr);
  45.182    // This is not needed any more, after the CSet choosing code was
  45.183    // changed to use the pause prediction work. But let's leave the
  45.184    // hook in just in case.
    46.1 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Wed Apr 01 22:31:26 2009 -0700
    46.2 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Apr 02 17:01:00 2009 -0700
    46.3 @@ -157,7 +157,6 @@
    46.4  class G1PrepareCompactClosure: public HeapRegionClosure {
    46.5    ModRefBarrierSet* _mrbs;
    46.6    CompactPoint _cp;
    46.7 -  bool _popular_only;
    46.8  
    46.9    void free_humongous_region(HeapRegion* hr) {
   46.10      HeapWord* bot = hr->bottom();
   46.11 @@ -172,17 +171,11 @@
   46.12    }
   46.13  
   46.14  public:
   46.15 -  G1PrepareCompactClosure(CompactibleSpace* cs, bool popular_only) :
   46.16 +  G1PrepareCompactClosure(CompactibleSpace* cs) :
   46.17      _cp(NULL, cs, cs->initialize_threshold()),
   46.18 -    _mrbs(G1CollectedHeap::heap()->mr_bs()),
   46.19 -    _popular_only(popular_only)
   46.20 +    _mrbs(G1CollectedHeap::heap()->mr_bs())
   46.21    {}
   46.22    bool doHeapRegion(HeapRegion* hr) {
   46.23 -    if (_popular_only && !hr->popular())
   46.24 -      return true; // terminate early
   46.25 -    else if (!_popular_only && hr->popular())
   46.26 -      return false; // skip this one.
   46.27 -
   46.28      if (hr->isHumongous()) {
   46.29        if (hr->startsHumongous()) {
   46.30          oop obj = oop(hr->bottom());
   46.31 @@ -203,20 +196,15 @@
   46.32      return false;
   46.33    }
   46.34  };
   46.35 -// Stolen verbatim from g1CollectedHeap.cpp
   46.36 +
   46.37 +// Finds the first HeapRegion.
   46.38  class FindFirstRegionClosure: public HeapRegionClosure {
   46.39    HeapRegion* _a_region;
   46.40 -  bool _find_popular;
   46.41  public:
   46.42 -  FindFirstRegionClosure(bool find_popular) :
   46.43 -    _a_region(NULL), _find_popular(find_popular) {}
   46.44 +  FindFirstRegionClosure() : _a_region(NULL) {}
   46.45    bool doHeapRegion(HeapRegion* r) {
   46.46 -    if (r->popular() == _find_popular) {
   46.47 -      _a_region = r;
   46.48 -      return true;
   46.49 -    } else {
   46.50 -      return false;
   46.51 -    }
   46.52 +    _a_region = r;
   46.53 +    return true;
   46.54    }
   46.55    HeapRegion* result() { return _a_region; }
   46.56  };
   46.57 @@ -242,30 +230,15 @@
   46.58    TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty);
   46.59    GenMarkSweep::trace("2");
   46.60  
   46.61 -  // First we compact the popular regions.
   46.62 -  if (G1NumPopularRegions > 0) {
   46.63 -    CompactibleSpace* sp = g1h->first_compactible_space();
   46.64 -    FindFirstRegionClosure cl(true /*find_popular*/);
   46.65 -    g1h->heap_region_iterate(&cl);
   46.66 -    HeapRegion *r = cl.result();
   46.67 -    assert(r->popular(), "should have found a popular region.");
   46.68 -    assert(r == sp, "first popular heap region should "
   46.69 -                    "== first compactible space");
   46.70 -    G1PrepareCompactClosure blk(sp, true/*popular_only*/);
   46.71 -    g1h->heap_region_iterate(&blk);
   46.72 -  }
   46.73 -
   46.74 -  // Now we do the regular regions.
   46.75 -  FindFirstRegionClosure cl(false /*find_popular*/);
   46.76 +  FindFirstRegionClosure cl;
   46.77    g1h->heap_region_iterate(&cl);
   46.78    HeapRegion *r = cl.result();
   46.79 -  assert(!r->popular(), "should have founda non-popular region.");
   46.80    CompactibleSpace* sp = r;
   46.81    if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) {
   46.82      sp = r->next_compaction_space();
   46.83    }
   46.84  
   46.85 -  G1PrepareCompactClosure blk(sp, false/*popular_only*/);
   46.86 +  G1PrepareCompactClosure blk(sp);
   46.87    g1h->heap_region_iterate(&blk);
   46.88  
   46.89    CompactPoint perm_cp(pg, NULL, NULL);
    47.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Apr 01 22:31:26 2009 -0700
    47.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Apr 02 17:01:00 2009 -0700
    47.3 @@ -580,9 +580,7 @@
    47.4    virtual void do_oop(oop* p) {
    47.5      HeapRegion* to = _g1->heap_region_containing(*p);
    47.6      if (to->in_collection_set()) {
    47.7 -      if (to->rem_set()->add_reference(p, 0)) {
    47.8 -        _g1->schedule_popular_region_evac(to);
    47.9 -      }
   47.10 +      to->rem_set()->add_reference(p, 0);
   47.11      }
   47.12    }
   47.13  };
   47.14 @@ -1024,9 +1022,8 @@
   47.15      gclog_or_tty->print_cr("    %d occupied cards represented.",
   47.16                             blk.occupied());
   47.17      gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
   47.18 -                           " %s, cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
   47.19 +                           ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
   47.20                             blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
   47.21 -                           (blk.max_mem_sz_region()->popular() ? "POP" : ""),
   47.22                             (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
   47.23                             (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
   47.24      gclog_or_tty->print_cr("    Did %d coarsenings.",
    48.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Wed Apr 01 22:31:26 2009 -0700
    48.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Thu Apr 02 17:01:00 2009 -0700
    48.3 @@ -65,7 +65,6 @@
    48.4    HeapRegion* to = _g1->heap_region_containing(obj);
    48.5    // The test below could be optimized by applying a bit op to to and from.
    48.6    if (to != NULL && from != NULL && from != to) {
    48.7 -    bool update_delayed = false;
    48.8      // There is a tricky infinite loop if we keep pushing
    48.9      // self forwarding pointers onto our _new_refs list.
   48.10      // The _par_traversal_in_progress flag is true during the collection pause,
   48.11 @@ -77,10 +76,7 @@
   48.12        // or processed (if an evacuation failure occurs) at the end
   48.13        // of the collection.
   48.14        // See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do().
   48.15 -      update_delayed = true;
   48.16 -    }
   48.17 -
   48.18 -    if (!to->popular() && !update_delayed) {
   48.19 +    } else {
   48.20  #if G1_REM_SET_LOGGING
   48.21        gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
   48.22                               " for region [" PTR_FORMAT ", " PTR_FORMAT ")",
   48.23 @@ -88,9 +84,7 @@
   48.24                               to->bottom(), to->end());
   48.25  #endif
   48.26        assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
   48.27 -      if (to->rem_set()->add_reference(p, tid)) {
   48.28 -        _g1->schedule_popular_region_evac(to);
   48.29 -      }
   48.30 +      to->rem_set()->add_reference(p, tid);
   48.31      }
   48.32    }
   48.33  }
    49.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Apr 01 22:31:26 2009 -0700
    49.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Thu Apr 02 17:01:00 2009 -0700
    49.3 @@ -185,15 +185,9 @@
    49.4    product(intx, G1InefficientPausePct, 80,                                  \
    49.5            "Threshold of an 'inefficient' pauses (as % of cum efficiency.")  \
    49.6                                                                              \
    49.7 -  product(intx, G1RSPopLimit, 32768,                                        \
    49.8 -          "Limit that defines popularity.  Should go away! XXX")            \
    49.9 -                                                                            \
   49.10    develop(bool, G1RSCountHisto, false,                                      \
   49.11            "If true, print a histogram of RS occupancies after each pause")  \
   49.12                                                                              \
   49.13 -  product(intx, G1ObjPopLimit, 256,                                         \
   49.14 -          "Limit that defines popularity for an object.")                   \
   49.15 -                                                                            \
   49.16    product(bool, G1TraceFileOverwrite, false,                                \
   49.17            "Allow the trace file to be overwritten")                         \
   49.18                                                                              \
   49.19 @@ -201,16 +195,6 @@
   49.20            "When > 0, print the occupancies of the <n> best and worst"       \
   49.21            "regions.")                                                       \
   49.22                                                                              \
   49.23 -  develop(bool, G1TracePopularity, false,                                   \
   49.24 -          "When true, provide detailed tracing of popularity.")             \
   49.25 -                                                                            \
   49.26 -  product(bool, G1SummarizePopularity, false,                               \
   49.27 -          "When true, provide end-of-run-summarization of popularity.")     \
   49.28 -                                                                            \
   49.29 -  product(intx, G1NumPopularRegions, 1,                                     \
   49.30 -          "Number of regions reserved to hold popular objects.  "           \
   49.31 -          "Should go away later.")                                          \
   49.32 -                                                                            \
   49.33    develop(bool, G1PrintParCleanupStats, false,                              \
   49.34            "When true, print extra stats about parallel cleanup.")           \
   49.35                                                                              \
    50.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Apr 01 22:31:26 2009 -0700
    50.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Apr 02 17:01:00 2009 -0700
    50.3 @@ -104,7 +104,6 @@
    50.4          HeapRegion* to   = _g1h->heap_region_containing(*p);
    50.5          if (from != NULL && to != NULL &&
    50.6              from != to &&
    50.7 -            !to->popular() &&
    50.8              !to->isHumongous()) {
    50.9            jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
   50.10            jbyte cv_field = *_bs->byte_for_const(p);
   50.11 @@ -285,8 +284,6 @@
   50.12    }
   50.13    zero_marked_bytes();
   50.14    set_sort_index(-1);
   50.15 -  if ((uintptr_t)bottom() >= (uintptr_t)g1h->popular_object_boundary())
   50.16 -    set_popular(false);
   50.17  
   50.18    _offsets.resize(HeapRegion::GrainWords);
   50.19    init_top_at_mark_start();
   50.20 @@ -371,7 +368,6 @@
   50.21      _next_in_special_set(NULL), _orig_end(NULL),
   50.22      _claimed(InitialClaimValue), _evacuation_failed(false),
   50.23      _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1),
   50.24 -    _popularity(NotPopular),
   50.25      _young_type(NotYoung), _next_young_region(NULL),
   50.26      _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1),
   50.27      _rem_set(NULL), _zfs(NotZeroFilled)
    51.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Apr 01 22:31:26 2009 -0700
    51.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Apr 02 17:01:00 2009 -0700
    51.3 @@ -238,15 +238,6 @@
    51.4    // See "sort_index" method.  -1 means is not in the array.
    51.5    int _sort_index;
    51.6  
    51.7 -  // Means it has (or at least had) a very large RS, and should not be
    51.8 -  // considered for membership in a collection set.
    51.9 -  enum PopularityState {
   51.10 -    NotPopular,
   51.11 -    PopularPending,
   51.12 -    Popular
   51.13 -  };
   51.14 -  PopularityState _popularity;
   51.15 -
   51.16    // <PREDICTION>
   51.17    double _gc_efficiency;
   51.18    // </PREDICTION>
   51.19 @@ -433,10 +424,6 @@
   51.20      _next_in_special_set = r;
   51.21    }
   51.22  
   51.23 -  bool is_reserved() {
   51.24 -    return popular();
   51.25 -  }
   51.26 -
   51.27    bool is_on_free_list() {
   51.28      return _is_on_free_list;
   51.29    }
   51.30 @@ -609,23 +596,6 @@
   51.31      init_top_at_mark_start();
   51.32    }
   51.33  
   51.34 -  bool popular() { return _popularity == Popular; }
   51.35 -  void set_popular(bool b) {
   51.36 -    if (b) {
   51.37 -      _popularity = Popular;
   51.38 -    } else {
   51.39 -      _popularity = NotPopular;
   51.40 -    }
   51.41 -  }
   51.42 -  bool popular_pending() { return _popularity == PopularPending; }
   51.43 -  void set_popular_pending(bool b) {
   51.44 -    if (b) {
   51.45 -      _popularity = PopularPending;
   51.46 -    } else {
   51.47 -      _popularity = NotPopular;
   51.48 -    }
   51.49 -  }
   51.50 -
   51.51    // <PREDICTION>
   51.52    void calc_gc_efficiency(void);
   51.53    double gc_efficiency() { return _gc_efficiency;}
    52.1 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Wed Apr 01 22:31:26 2009 -0700
    52.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Thu Apr 02 17:01:00 2009 -0700
    52.3 @@ -188,32 +188,6 @@
    52.4    // the _outgoing_region_map.
    52.5    void clear_outgoing_entries();
    52.6  
    52.7 -#if MAYBE
    52.8 -  // Audit the given card index.
    52.9 -  void audit_card(size_t card_num, HeapRegion* hr, u2* rc_arr,
   52.10 -                  HeapRegionRemSet* empty_cards, size_t* one_obj_cards);
   52.11 -
   52.12 -  // Assumes that "audit_stage1" has been called for "hr", to set up
   52.13 -  // "shadow" and "new_rs" appropriately.  Identifies individual popular
   52.14 -  // objects; returns "true" if any are found.
   52.15 -  bool audit_find_pop(HeapRegion* hr, u2* rc_arr);
   52.16 -
   52.17 -  // Assumes that "audit_stage1" has been called for "hr", to set up
   52.18 -  // "shadow" and "new_rs" appropriately.  Identifies individual popular
   52.19 -  // objects, and determines the number of entries in "new_rs" if any such
   52.20 -  // popular objects are ignored.  If this is sufficiently small, returns
   52.21 -  // "false" to indicate that a constraint should not be introduced.
   52.22 -  // Otherwise, returns "true" to indicate that we should go ahead with
   52.23 -  // adding the constraint.
   52.24 -  bool audit_stag(HeapRegion* hr, u2* rc_arr);
   52.25 -
   52.26 -
   52.27 -  u2* alloc_rc_array();
   52.28 -
   52.29 -  SeqHeapRegionRemSet* audit_post(u2* rc_arr, size_t multi_obj_crds,
   52.30 -                                  SeqHeapRegionRemSet* empty_cards);
   52.31 -#endif
   52.32 -
   52.33    enum ParIterState { Unclaimed, Claimed, Complete };
   52.34    ParIterState _iter_state;
   52.35  
   52.36 @@ -261,16 +235,14 @@
   52.37  
   52.38    /* Used in the sequential case.  Returns "true" iff this addition causes
   52.39       the size limit to be reached. */
   52.40 -  bool add_reference(oop* from) {
   52.41 +  void add_reference(oop* from) {
   52.42      _other_regions.add_reference(from);
   52.43 -    return false;
   52.44    }
   52.45  
   52.46    /* Used in the parallel case.  Returns "true" iff this addition causes
   52.47       the size limit to be reached. */
   52.48 -  bool add_reference(oop* from, int tid) {
   52.49 +  void add_reference(oop* from, int tid) {
   52.50      _other_regions.add_reference(from, tid);
   52.51 -    return false;
   52.52    }
   52.53  
   52.54    // Records the fact that the current region contains an outgoing
   52.55 @@ -338,20 +310,6 @@
   52.56    }
   52.57    void print() const;
   52.58  
   52.59 -#if MAYBE
   52.60 -  // We are about to introduce a constraint, requiring the collection time
   52.61 -  // of the region owning this RS to be <= "hr", and forgetting pointers
   52.62 -  // from the owning region to "hr."  Before doing so, examines this rem
   52.63 -  // set for pointers to "hr", possibly identifying some popular objects.,
   52.64 -  // and possibly finding some cards to no longer contain pointers to "hr",
   52.65 -  //
   52.66 -  // These steps may prevent the the constraint from being necessary; in
   52.67 -  // which case returns a set of cards now thought to contain no pointers
   52.68 -  // into HR.  In the normal (I assume) case, returns NULL, indicating that
   52.69 -  // we should go ahead and add the constraint.
   52.70 -  virtual SeqHeapRegionRemSet* audit(HeapRegion* hr) = 0;
   52.71 -#endif
   52.72 -
   52.73    // Called during a stop-world phase to perform any deferred cleanups.
   52.74    // The second version may be called by parallel threads after then finish
   52.75    // collection work.
    53.1 --- a/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Apr 01 22:31:26 2009 -0700
    53.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Thu Apr 02 17:01:00 2009 -0700
    53.3 @@ -74,7 +74,6 @@
    53.4      //       [first, cur)
    53.5      HeapRegion* curhr = _regions.at(cur);
    53.6      if (curhr->is_empty()
    53.7 -        && !curhr->is_reserved()
    53.8          && (first == cur
    53.9              || (_regions.at(cur-1)->end() ==
   53.10                  curhr->bottom()))) {
   53.11 @@ -121,35 +120,27 @@
   53.12    }
   53.13  }
   53.14  
   53.15 -void HeapRegionSeq::print_empty_runs(bool reserved_are_empty) {
   53.16 +void HeapRegionSeq::print_empty_runs() {
   53.17    int empty_run = 0;
   53.18    int n_empty = 0;
   53.19 -  bool at_least_one_reserved = false;
   53.20    int empty_run_start;
   53.21    for (int i = 0; i < _regions.length(); i++) {
   53.22      HeapRegion* r = _regions.at(i);
   53.23      if (r->continuesHumongous()) continue;
   53.24 -    if (r->is_empty() && (reserved_are_empty || !r->is_reserved())) {
   53.25 +    if (r->is_empty()) {
   53.26        assert(!r->isHumongous(), "H regions should not be empty.");
   53.27        if (empty_run == 0) empty_run_start = i;
   53.28        empty_run++;
   53.29        n_empty++;
   53.30 -      if (r->is_reserved()) {
   53.31 -        at_least_one_reserved = true;
   53.32 -      }
   53.33      } else {
   53.34        if (empty_run > 0) {
   53.35          gclog_or_tty->print("  %d:%d", empty_run_start, empty_run);
   53.36 -        if (reserved_are_empty && at_least_one_reserved)
   53.37 -          gclog_or_tty->print("(R)");
   53.38          empty_run = 0;
   53.39 -        at_least_one_reserved = false;
   53.40        }
   53.41      }
   53.42    }
   53.43    if (empty_run > 0) {
   53.44      gclog_or_tty->print(" %d:%d", empty_run_start, empty_run);
   53.45 -    if (reserved_are_empty && at_least_one_reserved) gclog_or_tty->print("(R)");
   53.46    }
   53.47    gclog_or_tty->print_cr(" [tot = %d]", n_empty);
   53.48  }
   53.49 @@ -193,7 +184,6 @@
   53.50    int cur = first;
   53.51    while (cur >= 0 &&
   53.52           (_regions.at(cur)->is_empty()
   53.53 -          && !_regions.at(cur)->is_reserved()
   53.54            && (first == cur
   53.55                || (_regions.at(cur+1)->bottom() ==
   53.56                    _regions.at(cur)->end())))) {
    54.1 --- a/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Wed Apr 01 22:31:26 2009 -0700
    54.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Thu Apr 02 17:01:00 2009 -0700
    54.3 @@ -104,8 +104,7 @@
    54.4  
    54.5    void print();
    54.6  
    54.7 -  // Prints out runs of empty regions.  If the arg is "true" reserved
    54.8 -  // (popular regions are considered "empty".
    54.9 -  void print_empty_runs(bool reserved_are_empty);
   54.10 +  // Prints out runs of empty regions.
   54.11 +  void print_empty_runs();
   54.12  
   54.13  };
    55.1 --- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Wed Apr 01 22:31:26 2009 -0700
    55.2 +++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Thu Apr 02 17:01:00 2009 -0700
    55.3 @@ -43,16 +43,9 @@
    55.4    JvmtiGCForAllocationMarker jgcm;
    55.5    G1CollectedHeap* g1h = G1CollectedHeap::heap();
    55.6    GCCauseSetter x(g1h, GCCause::_g1_inc_collection_pause);
    55.7 -  g1h->do_collection_pause_at_safepoint(NULL);
    55.8 +  g1h->do_collection_pause_at_safepoint();
    55.9  }
   55.10  
   55.11 -void VM_G1PopRegionCollectionPause::doit() {
   55.12 -  JvmtiGCForAllocationMarker jgcm;
   55.13 -  G1CollectedHeap* g1h = G1CollectedHeap::heap();
   55.14 -  g1h->do_collection_pause_at_safepoint(_pop_region);
   55.15 -}
   55.16 -
   55.17 -
   55.18  void VM_CGC_Operation::doit() {
   55.19    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
   55.20    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
    56.1 --- a/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp	Wed Apr 01 22:31:26 2009 -0700
    56.2 +++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp	Thu Apr 02 17:01:00 2009 -0700
    56.3 @@ -77,20 +77,6 @@
    56.4    }
    56.5  };
    56.6  
    56.7 -class VM_G1PopRegionCollectionPause: public VM_GC_Operation {
    56.8 -  HeapRegion* _pop_region;
    56.9 - public:
   56.10 -  VM_G1PopRegionCollectionPause(int gc_count_before, HeapRegion* pop_region) :
   56.11 -    VM_GC_Operation(gc_count_before),
   56.12 -    _pop_region(pop_region)
   56.13 -  {}
   56.14 -  virtual VMOp_Type type() const { return VMOp_G1PopRegionCollectionPause; }
   56.15 -  virtual void doit();
   56.16 -  virtual const char* name() const {
   56.17 -    return "garbage-first popular region collection pause";
   56.18 -  }
   56.19 -};
   56.20 -
   56.21  // Concurrent GC stop-the-world operations such as initial and final mark;
   56.22  // consider sharing these with CMS's counterparts.
   56.23  class VM_CGC_Operation: public VM_Operation {
    57.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Apr 01 22:31:26 2009 -0700
    57.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Apr 02 17:01:00 2009 -0700
    57.3 @@ -36,7 +36,7 @@
    57.4                                         ObjToScanQueueSet* work_queue_set_,
    57.5                                         size_t desired_plab_sz_,
    57.6                                         ParallelTaskTerminator& term_) :
    57.7 -  _to_space(to_space_), _old_gen(old_gen_), _thread_num(thread_num_),
    57.8 +  _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_),
    57.9    _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
   57.10    _ageTable(false), // false ==> not the global age table, no perf data.
   57.11    _to_space_alloc_buffer(desired_plab_sz_),
   57.12 @@ -57,6 +57,11 @@
   57.13    _start = os::elapsedTime();
   57.14    _old_gen_closure.set_generation(old_gen_);
   57.15    _old_gen_root_closure.set_generation(old_gen_);
   57.16 +  if (UseCompressedOops) {
   57.17 +    _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(512, true);
   57.18 +  } else {
   57.19 +    _overflow_stack = NULL;
   57.20 +  }
   57.21  }
   57.22  #ifdef _MSC_VER
   57.23  #pragma warning( pop )
   57.24 @@ -81,7 +86,7 @@
   57.25    assert(old->is_objArray(), "must be obj array");
   57.26    assert(old->is_forwarded(), "must be forwarded");
   57.27    assert(Universe::heap()->is_in_reserved(old), "must be in heap.");
   57.28 -  assert(!_old_gen->is_in(old), "must be in young generation.");
   57.29 +  assert(!old_gen()->is_in(old), "must be in young generation.");
   57.30  
   57.31    objArrayOop obj = objArrayOop(old->forwardee());
   57.32    // Process ParGCArrayScanChunk elements now
   57.33 @@ -119,26 +124,68 @@
   57.34  
   57.35  void ParScanThreadState::trim_queues(int max_size) {
   57.36    ObjToScanQueue* queue = work_queue();
   57.37 -  while (queue->size() > (juint)max_size) {
   57.38 -    oop obj_to_scan;
   57.39 -    if (queue->pop_local(obj_to_scan)) {
   57.40 -      note_pop();
   57.41 -
   57.42 -      if ((HeapWord *)obj_to_scan < young_old_boundary()) {
   57.43 -        if (obj_to_scan->is_objArray() &&
   57.44 -            obj_to_scan->is_forwarded() &&
   57.45 -            obj_to_scan->forwardee() != obj_to_scan) {
   57.46 -          scan_partial_array_and_push_remainder(obj_to_scan);
   57.47 +  do {
   57.48 +    while (queue->size() > (juint)max_size) {
   57.49 +      oop obj_to_scan;
   57.50 +      if (queue->pop_local(obj_to_scan)) {
   57.51 +        note_pop();
   57.52 +        if ((HeapWord *)obj_to_scan < young_old_boundary()) {
   57.53 +          if (obj_to_scan->is_objArray() &&
   57.54 +              obj_to_scan->is_forwarded() &&
   57.55 +              obj_to_scan->forwardee() != obj_to_scan) {
   57.56 +            scan_partial_array_and_push_remainder(obj_to_scan);
   57.57 +          } else {
   57.58 +            // object is in to_space
   57.59 +            obj_to_scan->oop_iterate(&_to_space_closure);
   57.60 +          }
   57.61          } else {
   57.62 -          // object is in to_space
   57.63 -          obj_to_scan->oop_iterate(&_to_space_closure);
   57.64 +          // object is in old generation
   57.65 +          obj_to_scan->oop_iterate(&_old_gen_closure);
   57.66          }
   57.67 -      } else {
   57.68 -        // object is in old generation
   57.69 -        obj_to_scan->oop_iterate(&_old_gen_closure);
   57.70        }
   57.71      }
   57.72 +    // For the  case of compressed oops, we have a private, non-shared
   57.73 +    // overflow stack, so we eagerly drain it so as to more evenly
   57.74 +    // distribute load early. Note: this may be good to do in
   57.75 +    // general rather than delay for the final stealing phase.
   57.76 +    // If applicable, we'll transfer a set of objects over to our
   57.77 +    // work queue, allowing them to be stolen and draining our
   57.78 +    // private overflow stack.
   57.79 +  } while (ParGCTrimOverflow && young_gen()->take_from_overflow_list(this));
   57.80 +}
   57.81 +
   57.82 +bool ParScanThreadState::take_from_overflow_stack() {
   57.83 +  assert(UseCompressedOops, "Else should not call");
   57.84 +  assert(young_gen()->overflow_list() == NULL, "Error");
   57.85 +  ObjToScanQueue* queue = work_queue();
   57.86 +  GrowableArray<oop>* of_stack = overflow_stack();
   57.87 +  uint num_overflow_elems = of_stack->length();
   57.88 +  uint num_take_elems     = MIN2(MIN2((queue->max_elems() - queue->size())/4,
   57.89 +                                      (juint)ParGCDesiredObjsFromOverflowList),
   57.90 +                                 num_overflow_elems);
   57.91 +  // Transfer the most recent num_take_elems from the overflow
   57.92 +  // stack to our work queue.
   57.93 +  for (size_t i = 0; i != num_take_elems; i++) {
   57.94 +    oop cur = of_stack->pop();
   57.95 +    oop obj_to_push = cur->forwardee();
   57.96 +    assert(Universe::heap()->is_in_reserved(cur), "Should be in heap");
   57.97 +    assert(!old_gen()->is_in_reserved(cur), "Should be in young gen");
   57.98 +    assert(Universe::heap()->is_in_reserved(obj_to_push), "Should be in heap");
   57.99 +    if (should_be_partially_scanned(obj_to_push, cur)) {
  57.100 +      assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
  57.101 +      obj_to_push = cur;
  57.102 +    }
  57.103 +    bool ok = queue->push(obj_to_push);
  57.104 +    assert(ok, "Should have succeeded");
  57.105    }
  57.106 +  assert(young_gen()->overflow_list() == NULL, "Error");
  57.107 +  return num_take_elems > 0;  // was something transferred?
  57.108 +}
  57.109 +
  57.110 +void ParScanThreadState::push_on_overflow_stack(oop p) {
  57.111 +  assert(UseCompressedOops, "Else should not call");
  57.112 +  overflow_stack()->push(p);
  57.113 +  assert(young_gen()->overflow_list() == NULL, "Error");
  57.114  }
  57.115  
  57.116  HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
  57.117 @@ -425,8 +472,7 @@
  57.118    ResourceMark rm;
  57.119    HandleMark hm;
  57.120    // We would need multiple old-gen queues otherwise.
  57.121 -  guarantee(gch->n_gens() == 2,
  57.122 -     "Par young collection currently only works with one older gen.");
  57.123 +  assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
  57.124  
  57.125    Generation* old_gen = gch->next_gen(_gen);
  57.126  
  57.127 @@ -1169,36 +1215,75 @@
  57.128  }
  57.129  #endif
  57.130  
  57.131 +// In case we are using compressed oops, we need to be careful.
  57.132 +// If the object being pushed is an object array, then its length
  57.133 +// field keeps track of the "grey boundary" at which the next
  57.134 +// incremental scan will be done (see ParGCArrayScanChunk).
  57.135 +// When using compressed oops, this length field is kept in the
  57.136 +// lower 32 bits of the erstwhile klass word and cannot be used
  57.137 +// for the overflow chaining pointer (OCP below). As such the OCP
  57.138 +// would itself need to be compressed into the top 32-bits in this
  57.139 +// case. Unfortunately, see below, in the event that we have a
  57.140 +// promotion failure, the node to be pushed on the list can be
  57.141 +// outside of the Java heap, so the heap-based pointer compression
  57.142 +// would not work (we would have potential aliasing between C-heap
  57.143 +// and Java-heap pointers). For this reason, when using compressed
  57.144 +// oops, we simply use a worker-thread-local, non-shared overflow
  57.145 +// list in the form of a growable array, with a slightly different
  57.146 +// overflow stack draining strategy. If/when we start using fat
  57.147 +// stacks here, we can go back to using (fat) pointer chains
  57.148 +// (although some performance comparisons would be useful since
  57.149 +// single global lists have their own performance disadvantages
  57.150 +// as we were made painfully aware not long ago, see 6786503).
  57.151  #define BUSY (oop(0x1aff1aff))
  57.152  void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) {
  57.153 -  // if the object has been forwarded to itself, then we cannot
  57.154 -  // use the klass pointer for the linked list.  Instead we have
  57.155 -  // to allocate an oopDesc in the C-Heap and use that for the linked list.
  57.156 -  // XXX This is horribly inefficient when a promotion failure occurs
  57.157 -  // and should be fixed. XXX FIX ME !!!
  57.158 +  assert(is_in_reserved(from_space_obj), "Should be from this generation");
  57.159 +  if (UseCompressedOops) {
  57.160 +    // In the case of compressed oops, we use a private, not-shared
  57.161 +    // overflow stack.
  57.162 +    par_scan_state->push_on_overflow_stack(from_space_obj);
  57.163 +  } else {
  57.164 +    // if the object has been forwarded to itself, then we cannot
  57.165 +    // use the klass pointer for the linked list.  Instead we have
  57.166 +    // to allocate an oopDesc in the C-Heap and use that for the linked list.
  57.167 +    // XXX This is horribly inefficient when a promotion failure occurs
  57.168 +    // and should be fixed. XXX FIX ME !!!
  57.169  #ifndef PRODUCT
  57.170 -  Atomic::inc_ptr(&_num_par_pushes);
  57.171 -  assert(_num_par_pushes > 0, "Tautology");
  57.172 +    Atomic::inc_ptr(&_num_par_pushes);
  57.173 +    assert(_num_par_pushes > 0, "Tautology");
  57.174  #endif
  57.175 -  if (from_space_obj->forwardee() == from_space_obj) {
  57.176 -    oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1);
  57.177 -    listhead->forward_to(from_space_obj);
  57.178 -    from_space_obj = listhead;
  57.179 +    if (from_space_obj->forwardee() == from_space_obj) {
  57.180 +      oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1);
  57.181 +      listhead->forward_to(from_space_obj);
  57.182 +      from_space_obj = listhead;
  57.183 +    }
  57.184 +    oop observed_overflow_list = _overflow_list;
  57.185 +    oop cur_overflow_list;
  57.186 +    do {
  57.187 +      cur_overflow_list = observed_overflow_list;
  57.188 +      if (cur_overflow_list != BUSY) {
  57.189 +        from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
  57.190 +      } else {
  57.191 +        from_space_obj->set_klass_to_list_ptr(NULL);
  57.192 +      }
  57.193 +      observed_overflow_list =
  57.194 +        (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
  57.195 +    } while (cur_overflow_list != observed_overflow_list);
  57.196    }
  57.197 -  oop observed_overflow_list = _overflow_list;
  57.198 -  oop cur_overflow_list;
  57.199 -  do {
  57.200 -    cur_overflow_list = observed_overflow_list;
  57.201 -    if (cur_overflow_list != BUSY) {
  57.202 -      from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
  57.203 -    } else {
  57.204 -      from_space_obj->set_klass_to_list_ptr(NULL);
  57.205 -    }
  57.206 -    observed_overflow_list =
  57.207 -      (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
  57.208 -  } while (cur_overflow_list != observed_overflow_list);
  57.209  }
  57.210  
  57.211 +bool ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
  57.212 +  bool res;
  57.213 +
  57.214 +  if (UseCompressedOops) {
  57.215 +    res = par_scan_state->take_from_overflow_stack();
  57.216 +  } else {
  57.217 +    res = take_from_overflow_list_work(par_scan_state);
  57.218 +  }
  57.219 +  return res;
  57.220 +}
  57.221 +
  57.222 +
  57.223  // *NOTE*: The overflow list manipulation code here and
  57.224  // in CMSCollector:: are very similar in shape,
  57.225  // except that in the CMS case we thread the objects
  57.226 @@ -1213,14 +1298,13 @@
  57.227  // similar changes might be needed.
  57.228  // See CMSCollector::par_take_from_overflow_list() for
  57.229  // more extensive documentation comments.
  57.230 -bool
  57.231 -ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
  57.232 +bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan_state) {
  57.233    ObjToScanQueue* work_q = par_scan_state->work_queue();
  57.234 -  assert(work_q->size() == 0, "Should first empty local work queue");
  57.235    // How many to take?
  57.236 -  size_t objsFromOverflow = MIN2((size_t)work_q->max_elems()/4,
  57.237 +  size_t objsFromOverflow = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
  57.238                                   (size_t)ParGCDesiredObjsFromOverflowList);
  57.239  
  57.240 +  assert(par_scan_state->overflow_stack() == NULL, "Error");
  57.241    if (_overflow_list == NULL) return false;
  57.242  
  57.243    // Otherwise, there was something there; try claiming the list.
    58.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Wed Apr 01 22:31:26 2009 -0700
    58.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Thu Apr 02 17:01:00 2009 -0700
    58.3 @@ -55,6 +55,7 @@
    58.4    friend class ParScanThreadStateSet;
    58.5   private:
    58.6    ObjToScanQueue *_work_queue;
    58.7 +  GrowableArray<oop>* _overflow_stack;
    58.8  
    58.9    ParGCAllocBuffer _to_space_alloc_buffer;
   58.10  
   58.11 @@ -79,6 +80,9 @@
   58.12    Space* _to_space;
   58.13    Space* to_space() { return _to_space; }
   58.14  
   58.15 +  ParNewGeneration* _young_gen;
   58.16 +  ParNewGeneration* young_gen() const { return _young_gen; }
   58.17 +
   58.18    Generation* _old_gen;
   58.19    Generation* old_gen() { return _old_gen; }
   58.20  
   58.21 @@ -134,6 +138,11 @@
   58.22    // Decrease queue size below "max_size".
   58.23    void trim_queues(int max_size);
   58.24  
   58.25 +  // Private overflow stack usage
   58.26 +  GrowableArray<oop>* overflow_stack() { return _overflow_stack; }
   58.27 +  bool take_from_overflow_stack();
   58.28 +  void push_on_overflow_stack(oop p);
   58.29 +
   58.30    // Is new_obj a candidate for scan_partial_array_and_push_remainder method.
   58.31    inline bool should_be_partially_scanned(oop new_obj, oop old_obj) const;
   58.32  
   58.33 @@ -378,13 +387,17 @@
   58.34    NOT_PRODUCT(int _overflow_counter;)
   58.35    NOT_PRODUCT(bool should_simulate_overflow();)
   58.36  
   58.37 +  // Accessor for overflow list
   58.38 +  oop overflow_list() { return _overflow_list; }
   58.39 +
   58.40    // Push the given (from-space) object on the global overflow list.
   58.41    void push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state);
   58.42  
   58.43    // If the global overflow list is non-empty, move some tasks from it
   58.44 -  // onto "work_q" (which must be empty).  No more than 1/4 of the
   58.45 -  // max_elems of "work_q" are moved.
   58.46 +  // onto "work_q" (which need not be empty).  No more than 1/4 of the
   58.47 +  // available space on "work_q" is used.
   58.48    bool take_from_overflow_list(ParScanThreadState* par_scan_state);
   58.49 +  bool take_from_overflow_list_work(ParScanThreadState* par_scan_state);
   58.50  
   58.51    // The task queues to be used by parallel GC threads.
   58.52    ObjToScanQueueSet* task_queues() {
    59.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Apr 01 22:31:26 2009 -0700
    59.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Apr 02 17:01:00 2009 -0700
    59.3 @@ -1,5 +1,5 @@
    59.4  /*
    59.5 - * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
    59.6 + * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
    59.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    59.8   *
    59.9   * This code is free software; you can redistribute it and/or modify it
   59.10 @@ -825,6 +825,7 @@
   59.11    if (young_gen()->is_in_reserved(addr)) {
   59.12      assert(young_gen()->is_in(addr),
   59.13             "addr should be in allocated part of young gen");
   59.14 +    if (Debugging)  return NULL;  // called from find() in debug.cpp
   59.15      Unimplemented();
   59.16    } else if (old_gen()->is_in_reserved(addr)) {
   59.17      assert(old_gen()->is_in(addr),
    60.1 --- a/src/share/vm/gc_interface/gcCause.hpp	Wed Apr 01 22:31:26 2009 -0700
    60.2 +++ b/src/share/vm/gc_interface/gcCause.hpp	Thu Apr 02 17:01:00 2009 -0700
    60.3 @@ -60,7 +60,7 @@
    60.4      _old_generation_too_full_to_scavenge,
    60.5      _adaptive_size_policy,
    60.6  
    60.7 -    _g1_inc_collection_pause, _g1_pop_region_collection_pause,
    60.8 +    _g1_inc_collection_pause,
    60.9  
   60.10      _last_ditch_collection,
   60.11      _last_gc_cause
    61.1 --- a/src/share/vm/includeDB_core	Wed Apr 01 22:31:26 2009 -0700
    61.2 +++ b/src/share/vm/includeDB_core	Thu Apr 02 17:01:00 2009 -0700
    61.3 @@ -3154,6 +3154,8 @@
    61.4  oopsHierarchy.cpp                       thread_<os_family>.inline.hpp
    61.5  
    61.6  orderAccess.cpp                         orderAccess.hpp
    61.7 +orderAccess.cpp                         stubRoutines.hpp
    61.8 +orderAccess.cpp                         thread.hpp
    61.9  
   61.10  orderAccess.hpp                         allocation.hpp
   61.11  orderAccess.hpp                         os.hpp
    62.1 --- a/src/share/vm/oops/instanceKlass.cpp	Wed Apr 01 22:31:26 2009 -0700
    62.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Thu Apr 02 17:01:00 2009 -0700
    62.3 @@ -1,5 +1,5 @@
    62.4  /*
    62.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    62.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    62.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    62.8   *
    62.9   * This code is free software; you can redistribute it and/or modify it
   62.10 @@ -1813,6 +1813,8 @@
   62.11                                            oop class_loader2, symbolOop class_name2) {
   62.12    if (class_loader1 != class_loader2) {
   62.13      return false;
   62.14 +  } else if (class_name1 == class_name2) {
   62.15 +    return true;                // skip painful bytewise comparison
   62.16    } else {
   62.17      ResourceMark rm;
   62.18  
   62.19 @@ -1879,6 +1881,56 @@
   62.20     return(is_same_class_package(targetclassloader(), targetclassname()));
   62.21  }
   62.22  
   62.23 +/* defined for now in jvm.cpp, for historical reasons *--
   62.24 +klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle self,
   62.25 +                                                     symbolOop& simple_name_result, TRAPS) {
   62.26 +  ...
   62.27 +}
   62.28 +*/
   62.29 +
   62.30 +// tell if two classes have the same enclosing class (at package level)
   62.31 +bool instanceKlass::is_same_package_member_impl(instanceKlassHandle class1,
   62.32 +                                                klassOop class2_oop, TRAPS) {
   62.33 +  if (class2_oop == class1->as_klassOop())          return true;
   62.34 +  if (!Klass::cast(class2_oop)->oop_is_instance())  return false;
   62.35 +  instanceKlassHandle class2(THREAD, class2_oop);
   62.36 +
   62.37 +  // must be in same package before we try anything else
   62.38 +  if (!class1->is_same_class_package(class2->class_loader(), class2->name()))
   62.39 +    return false;
   62.40 +
   62.41 +  // As long as there is an outer1.getEnclosingClass,
   62.42 +  // shift the search outward.
   62.43 +  instanceKlassHandle outer1 = class1;
   62.44 +  for (;;) {
   62.45 +    // As we walk along, look for equalities between outer1 and class2.
   62.46 +    // Eventually, the walks will terminate as outer1 stops
   62.47 +    // at the top-level class around the original class.
   62.48 +    symbolOop ignore_name;
   62.49 +    klassOop next = outer1->compute_enclosing_class(ignore_name, CHECK_false);
   62.50 +    if (next == NULL)  break;
   62.51 +    if (next == class2())  return true;
   62.52 +    outer1 = instanceKlassHandle(THREAD, next);
   62.53 +  }
   62.54 +
   62.55 +  // Now do the same for class2.
   62.56 +  instanceKlassHandle outer2 = class2;
   62.57 +  for (;;) {
   62.58 +    symbolOop ignore_name;
   62.59 +    klassOop next = outer2->compute_enclosing_class(ignore_name, CHECK_false);
   62.60 +    if (next == NULL)  break;
   62.61 +    // Might as well check the new outer against all available values.
   62.62 +    if (next == class1())  return true;
   62.63 +    if (next == outer1())  return true;
   62.64 +    outer2 = instanceKlassHandle(THREAD, next);
   62.65 +  }
   62.66 +
   62.67 +  // If by this point we have not found an equality between the
   62.68 +  // two classes, we know they are in separate package members.
   62.69 +  return false;
   62.70 +}
   62.71 +
   62.72 +
   62.73  jint instanceKlass::compute_modifier_flags(TRAPS) const {
   62.74    klassOop k = as_klassOop();
   62.75    jint access = access_flags().as_int();
   62.76 @@ -2015,9 +2067,11 @@
   62.77  
   62.78  // Printing
   62.79  
   62.80 +#define BULLET  " - "
   62.81 +
   62.82  void FieldPrinter::do_field(fieldDescriptor* fd) {
   62.83 -   if (fd->is_static() == (_obj == NULL)) {
   62.84 -     _st->print("   - ");
   62.85 +  _st->print(BULLET);
   62.86 +   if (fd->is_static() || (_obj == NULL)) {
   62.87       fd->print_on(_st);
   62.88       _st->cr();
   62.89     } else {
   62.90 @@ -2038,7 +2092,7 @@
   62.91          value->is_typeArray() &&
   62.92          offset          <= (juint) value->length() &&
   62.93          offset + length <= (juint) value->length()) {
   62.94 -      st->print("string: ");
   62.95 +      st->print(BULLET"string: ");
   62.96        Handle h_obj(obj);
   62.97        java_lang_String::print(h_obj, st);
   62.98        st->cr();
   62.99 @@ -2046,23 +2100,26 @@
  62.100      }
  62.101    }
  62.102  
  62.103 -  st->print_cr("fields:");
  62.104 +  st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj));
  62.105    FieldPrinter print_nonstatic_field(st, obj);
  62.106    do_nonstatic_fields(&print_nonstatic_field);
  62.107  
  62.108    if (as_klassOop() == SystemDictionary::class_klass()) {
  62.109 +    st->print(BULLET"signature: ");
  62.110 +    java_lang_Class::print_signature(obj, st);
  62.111 +    st->cr();
  62.112      klassOop mirrored_klass = java_lang_Class::as_klassOop(obj);
  62.113 -    st->print("   - fake entry for mirror: ");
  62.114 +    st->print(BULLET"fake entry for mirror: ");
  62.115      mirrored_klass->print_value_on(st);
  62.116      st->cr();
  62.117 -    st->print("   - fake entry resolved_constructor: ");
  62.118 +    st->print(BULLET"fake entry resolved_constructor: ");
  62.119      methodOop ctor = java_lang_Class::resolved_constructor(obj);
  62.120      ctor->print_value_on(st);
  62.121      klassOop array_klass = java_lang_Class::array_klass(obj);
  62.122 -    st->print("   - fake entry for array: ");
  62.123 +    st->cr();
  62.124 +    st->print(BULLET"fake entry for array: ");
  62.125      array_klass->print_value_on(st);
  62.126      st->cr();
  62.127 -    st->cr();
  62.128    }
  62.129  }
  62.130  
  62.131 @@ -2070,6 +2127,28 @@
  62.132    st->print("a ");
  62.133    name()->print_value_on(st);
  62.134    obj->print_address_on(st);
  62.135 +  if (as_klassOop() == SystemDictionary::string_klass()
  62.136 +      && java_lang_String::value(obj) != NULL) {
  62.137 +    ResourceMark rm;
  62.138 +    int len = java_lang_String::length(obj);
  62.139 +    int plen = (len < 24 ? len : 12);
  62.140 +    char* str = java_lang_String::as_utf8_string(obj, 0, plen);
  62.141 +    st->print(" = \"%s\"", str);
  62.142 +    if (len > plen)
  62.143 +      st->print("...[%d]", len);
  62.144 +  } else if (as_klassOop() == SystemDictionary::class_klass()) {
  62.145 +    klassOop k = java_lang_Class::as_klassOop(obj);
  62.146 +    st->print(" = ");
  62.147 +    if (k != NULL) {
  62.148 +      k->print_value_on(st);
  62.149 +    } else {
  62.150 +      const char* tname = type2name(java_lang_Class::primitive_type(obj));
  62.151 +      st->print("%s", tname ? tname : "type?");
  62.152 +    }
  62.153 +  } else if (java_lang_boxing_object::is_instance(obj)) {
  62.154 +    st->print(" = ");
  62.155 +    java_lang_boxing_object::print(obj, st);
  62.156 +  }
  62.157  }
  62.158  
  62.159  #endif // ndef PRODUCT
    63.1 --- a/src/share/vm/oops/instanceKlass.hpp	Wed Apr 01 22:31:26 2009 -0700
    63.2 +++ b/src/share/vm/oops/instanceKlass.hpp	Thu Apr 02 17:01:00 2009 -0700
    63.3 @@ -1,5 +1,5 @@
    63.4  /*
    63.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    63.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    63.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    63.8   *
    63.9   * This code is free software; you can redistribute it and/or modify it
   63.10 @@ -311,6 +311,22 @@
   63.11    bool is_same_class_package(oop classloader2, symbolOop classname2);
   63.12    static bool is_same_class_package(oop class_loader1, symbolOop class_name1, oop class_loader2, symbolOop class_name2);
   63.13  
   63.14 +  // find an enclosing class (defined where original code was, in jvm.cpp!)
   63.15 +  klassOop compute_enclosing_class(symbolOop& simple_name_result, TRAPS) {
   63.16 +    instanceKlassHandle self(THREAD, this->as_klassOop());
   63.17 +    return compute_enclosing_class_impl(self, simple_name_result, THREAD);
   63.18 +  }
   63.19 +  static klassOop compute_enclosing_class_impl(instanceKlassHandle self,
   63.20 +                                               symbolOop& simple_name_result, TRAPS);
   63.21 +
   63.22 +  // tell if two classes have the same enclosing class (at package level)
   63.23 +  bool is_same_package_member(klassOop class2, TRAPS) {
   63.24 +    instanceKlassHandle self(THREAD, this->as_klassOop());
   63.25 +    return is_same_package_member_impl(self, class2, THREAD);
   63.26 +  }
   63.27 +  static bool is_same_package_member_impl(instanceKlassHandle self,
   63.28 +                                          klassOop class2, TRAPS);
   63.29 +
   63.30    // initialization state
   63.31    bool is_loaded() const                   { return _init_state >= loaded; }
   63.32    bool is_linked() const                   { return _init_state >= linked; }
    64.1 --- a/src/share/vm/oops/instanceKlassKlass.cpp	Wed Apr 01 22:31:26 2009 -0700
    64.2 +++ b/src/share/vm/oops/instanceKlassKlass.cpp	Thu Apr 02 17:01:00 2009 -0700
    64.3 @@ -1,5 +1,5 @@
    64.4  /*
    64.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    64.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    64.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    64.8   *
    64.9   * This code is free software; you can redistribute it and/or modify it
   64.10 @@ -487,6 +487,8 @@
   64.11  
   64.12  // Printing
   64.13  
   64.14 +#define BULLET  " - "
   64.15 +
   64.16  static const char* state_names[] = {
   64.17    "unparseable_by_gc", "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error"
   64.18  };
   64.19 @@ -497,13 +499,13 @@
   64.20    instanceKlass* ik = instanceKlass::cast(klassOop(obj));
   64.21    klassKlass::oop_print_on(obj, st);
   64.22  
   64.23 -  st->print(" - instance size:     %d", ik->size_helper());                        st->cr();
   64.24 -  st->print(" - klass size:        %d", ik->object_size());                        st->cr();
   64.25 -  st->print(" - access:            "); ik->access_flags().print_on(st);            st->cr();
   64.26 -  st->print(" - state:             "); st->print_cr(state_names[ik->_init_state]);
   64.27 -  st->print(" - name:              "); ik->name()->print_value_on(st);             st->cr();
   64.28 -  st->print(" - super:             "); ik->super()->print_value_on(st);            st->cr();
   64.29 -  st->print(" - sub:               ");
   64.30 +  st->print(BULLET"instance size:     %d", ik->size_helper());                        st->cr();
   64.31 +  st->print(BULLET"klass size:        %d", ik->object_size());                        st->cr();
   64.32 +  st->print(BULLET"access:            "); ik->access_flags().print_on(st);            st->cr();
   64.33 +  st->print(BULLET"state:             "); st->print_cr(state_names[ik->_init_state]);
   64.34 +  st->print(BULLET"name:              "); ik->name()->print_value_on(st);             st->cr();
   64.35 +  st->print(BULLET"super:             "); ik->super()->print_value_on(st);            st->cr();
   64.36 +  st->print(BULLET"sub:               ");
   64.37    Klass* sub = ik->subklass();
   64.38    int n;
   64.39    for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) {
   64.40 @@ -516,12 +518,12 @@
   64.41    st->cr();
   64.42  
   64.43    if (ik->is_interface()) {
   64.44 -    st->print_cr(" - nof implementors:  %d", ik->nof_implementors());
   64.45 +    st->print_cr(BULLET"nof implementors:  %d", ik->nof_implementors());
   64.46      int print_impl = 0;
   64.47      for (int i = 0; i < instanceKlass::implementors_limit; i++) {
   64.48        if (ik->implementor(i) != NULL) {
   64.49          if (++print_impl == 1)
   64.50 -          st->print_cr(" - implementor:    ");
   64.51 +          st->print_cr(BULLET"implementor:    ");
   64.52          st->print("   ");
   64.53          ik->implementor(i)->print_value_on(st);
   64.54        }
   64.55 @@ -529,34 +531,33 @@
   64.56      if (print_impl > 0)  st->cr();
   64.57    }
   64.58  
   64.59 -  st->print(" - arrays:            "); ik->array_klasses()->print_value_on(st);     st->cr();
   64.60 -  st->print(" - methods:           "); ik->methods()->print_value_on(st);           st->cr();
   64.61 +  st->print(BULLET"arrays:            "); ik->array_klasses()->print_value_on(st);     st->cr();
   64.62 +  st->print(BULLET"methods:           "); ik->methods()->print_value_on(st);           st->cr();
   64.63    if (Verbose) {
   64.64      objArrayOop methods = ik->methods();
   64.65      for(int i = 0; i < methods->length(); i++) {
   64.66        tty->print("%d : ", i); methods->obj_at(i)->print_value(); tty->cr();
   64.67      }
   64.68    }
   64.69 -  st->print(" - method ordering:   "); ik->method_ordering()->print_value_on(st);       st->cr();
   64.70 -  st->print(" - local interfaces:  "); ik->local_interfaces()->print_value_on(st);      st->cr();
   64.71 -  st->print(" - trans. interfaces: "); ik->transitive_interfaces()->print_value_on(st); st->cr();
   64.72 -  st->print(" - constants:         "); ik->constants()->print_value_on(st);         st->cr();
   64.73 -  st->print(" - class loader:      "); ik->class_loader()->print_value_on(st);      st->cr();
   64.74 -  st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
   64.75 -  st->print(" - host class: ");        ik->host_klass()->print_value_on(st);        st->cr();
   64.76 -  st->print(" - signers:           "); ik->signers()->print_value_on(st);           st->cr();
   64.77 +  st->print(BULLET"method ordering:   "); ik->method_ordering()->print_value_on(st);       st->cr();
   64.78 +  st->print(BULLET"local interfaces:  "); ik->local_interfaces()->print_value_on(st);      st->cr();
   64.79 +  st->print(BULLET"trans. interfaces: "); ik->transitive_interfaces()->print_value_on(st); st->cr();
   64.80 +  st->print(BULLET"constants:         "); ik->constants()->print_value_on(st);         st->cr();
   64.81 +  st->print(BULLET"class loader:      "); ik->class_loader()->print_value_on(st);      st->cr();
   64.82 +  st->print(BULLET"protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
   64.83 +  st->print(BULLET"host class:        "); ik->host_klass()->print_value_on(st);        st->cr();
   64.84 +  st->print(BULLET"signers:           "); ik->signers()->print_value_on(st);           st->cr();
   64.85    if (ik->source_file_name() != NULL) {
   64.86 -    st->print(" - source file:       ");
   64.87 +    st->print(BULLET"source file:       ");
   64.88      ik->source_file_name()->print_value_on(st);
   64.89      st->cr();
   64.90    }
   64.91    if (ik->source_debug_extension() != NULL) {
   64.92 -    st->print(" - source debug extension:       ");
   64.93 +    st->print(BULLET"source debug extension:       ");
   64.94      ik->source_debug_extension()->print_value_on(st);
   64.95      st->cr();
   64.96    }
   64.97  
   64.98 -  st->print_cr(" - previous version:       ");
   64.99    {
  64.100      ResourceMark rm;
  64.101      // PreviousVersionInfo objects returned via PreviousVersionWalker
  64.102 @@ -564,38 +565,43 @@
  64.103      // GrowableArray _after_ the PreviousVersionWalker destructor
  64.104      // has destroyed the handles.
  64.105      {
  64.106 +      bool have_pv = false;
  64.107        PreviousVersionWalker pvw(ik);
  64.108        for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
  64.109             pv_info != NULL; pv_info = pvw.next_previous_version()) {
  64.110 +        if (!have_pv)
  64.111 +          st->print(BULLET"previous version:  ");
  64.112 +        have_pv = true;
  64.113          pv_info->prev_constant_pool_handle()()->print_value_on(st);
  64.114        }
  64.115 -      st->cr();
  64.116 +      if (have_pv)  st->cr();
  64.117      } // pvw is cleaned up
  64.118    } // rm is cleaned up
  64.119  
  64.120    if (ik->generic_signature() != NULL) {
  64.121 -    st->print(" - generic signature:            ");
  64.122 +    st->print(BULLET"generic signature: ");
  64.123      ik->generic_signature()->print_value_on(st);
  64.124 +    st->cr();
  64.125    }
  64.126 -  st->print(" - inner classes:     "); ik->inner_classes()->print_value_on(st);     st->cr();
  64.127 -  st->print(" - java mirror:       "); ik->java_mirror()->print_value_on(st);       st->cr();
  64.128 -  st->print(" - vtable length      %d  (start addr: " INTPTR_FORMAT ")", ik->vtable_length(), ik->start_of_vtable());  st->cr();
  64.129 -  st->print(" - itable length      %d (start addr: " INTPTR_FORMAT ")", ik->itable_length(), ik->start_of_itable()); st->cr();
  64.130 -  st->print_cr(" - static fields:");
  64.131 +  st->print(BULLET"inner classes:     "); ik->inner_classes()->print_value_on(st);     st->cr();
  64.132 +  st->print(BULLET"java mirror:       "); ik->java_mirror()->print_value_on(st);       st->cr();
  64.133 +  st->print(BULLET"vtable length      %d  (start addr: " INTPTR_FORMAT ")", ik->vtable_length(), ik->start_of_vtable());  st->cr();
  64.134 +  st->print(BULLET"itable length      %d (start addr: " INTPTR_FORMAT ")", ik->itable_length(), ik->start_of_itable()); st->cr();
  64.135 +  st->print_cr(BULLET"---- static fields (%d words):", ik->static_field_size());
  64.136    FieldPrinter print_static_field(st);
  64.137    ik->do_local_static_fields(&print_static_field);
  64.138 -  st->print_cr(" - non-static fields:");
  64.139 -  FieldPrinter print_nonstatic_field(st, obj);
  64.140 +  st->print_cr(BULLET"---- non-static fields (%d words):", ik->nonstatic_field_size());
  64.141 +  FieldPrinter print_nonstatic_field(st);
  64.142    ik->do_nonstatic_fields(&print_nonstatic_field);
  64.143  
  64.144 -  st->print(" - static oop maps:     ");
  64.145 +  st->print(BULLET"static oop maps:     ");
  64.146    if (ik->static_oop_field_size() > 0) {
  64.147      int first_offset = ik->offset_of_static_fields();
  64.148      st->print("%d-%d", first_offset, first_offset + ik->static_oop_field_size() - 1);
  64.149    }
  64.150    st->cr();
  64.151  
  64.152 -  st->print(" - non-static oop maps: ");
  64.153 +  st->print(BULLET"non-static oop maps: ");
  64.154    OopMapBlock* map     = ik->start_of_nonstatic_oop_maps();
  64.155    OopMapBlock* end_map = map + ik->nonstatic_oop_map_size();
  64.156    while (map < end_map) {
    65.1 --- a/src/share/vm/oops/klassVtable.cpp	Wed Apr 01 22:31:26 2009 -0700
    65.2 +++ b/src/share/vm/oops/klassVtable.cpp	Thu Apr 02 17:01:00 2009 -0700
    65.3 @@ -1,5 +1,5 @@
    65.4  /*
    65.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    65.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    65.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    65.8   *
    65.9   * This code is free software; you can redistribute it and/or modify it
   65.10 @@ -1148,6 +1148,27 @@
   65.11    return index;
   65.12  }
   65.13  
   65.14 +
   65.15 +// inverse to compute_itable_index
   65.16 +methodOop klassItable::method_for_itable_index(klassOop intf, int itable_index) {
   65.17 +  assert(instanceKlass::cast(intf)->is_interface(), "sanity check");
   65.18 +  objArrayOop methods = instanceKlass::cast(intf)->methods();
   65.19 +
   65.20 +  int index = itable_index;
   65.21 +  // Adjust for <clinit>, which is left out of table if first method
   65.22 +  if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->name() == vmSymbols::class_initializer_name()) {
   65.23 +    index++;
   65.24 +  }
   65.25 +
   65.26 +  if (itable_index < 0 || index >= methods->length())
   65.27 +    return NULL;                // help caller defend against bad indexes
   65.28 +
   65.29 +  methodOop m = (methodOop)methods->obj_at(index);
   65.30 +  assert(compute_itable_index(m) == itable_index, "correct inverse");
   65.31 +
   65.32 +  return m;
   65.33 +}
   65.34 +
   65.35  void klassVtable::verify(outputStream* st, bool forced) {
   65.36    // make sure table is initialized
   65.37    if (!Universe::is_fully_initialized()) return;
    66.1 --- a/src/share/vm/oops/klassVtable.hpp	Wed Apr 01 22:31:26 2009 -0700
    66.2 +++ b/src/share/vm/oops/klassVtable.hpp	Thu Apr 02 17:01:00 2009 -0700
    66.3 @@ -1,5 +1,5 @@
    66.4  /*
    66.5 - * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
    66.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    66.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    66.8   *
    66.9   * This code is free software; you can redistribute it and/or modify it
   66.10 @@ -301,6 +301,8 @@
   66.11  
   66.12    // Resolving of method to index
   66.13    static int compute_itable_index(methodOop m);
   66.14 +  // ...and back again:
   66.15 +  static methodOop method_for_itable_index(klassOop klass, int itable_index);
   66.16  
   66.17    // Debugging/Statistics
   66.18    static void print_statistics() PRODUCT_RETURN;
    67.1 --- a/src/share/vm/oops/methodKlass.cpp	Wed Apr 01 22:31:26 2009 -0700
    67.2 +++ b/src/share/vm/oops/methodKlass.cpp	Thu Apr 02 17:01:00 2009 -0700
    67.3 @@ -1,5 +1,5 @@
    67.4  /*
    67.5 - * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
    67.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    67.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    67.8   *
    67.9   * This code is free software; you can redistribute it and/or modify it
   67.10 @@ -247,9 +247,14 @@
   67.11    st->print_cr(" - size of params:    %d",   m->size_of_parameters());
   67.12    st->print_cr(" - method size:       %d",   m->method_size());
   67.13    st->print_cr(" - vtable index:      %d",   m->_vtable_index);
   67.14 +  st->print_cr(" - i2i entry:         " INTPTR_FORMAT, m->interpreter_entry());
   67.15 +  st->print_cr(" - adapter:           " INTPTR_FORMAT, m->adapter());
   67.16 +  st->print_cr(" - compiled entry     " INTPTR_FORMAT, m->from_compiled_entry());
   67.17    st->print_cr(" - code size:         %d",   m->code_size());
   67.18 -  st->print_cr(" - code start:        " INTPTR_FORMAT, m->code_base());
   67.19 -  st->print_cr(" - code end (excl):   " INTPTR_FORMAT, m->code_base() + m->code_size());
   67.20 +  if (m->code_size() != 0) {
   67.21 +    st->print_cr(" - code start:        " INTPTR_FORMAT, m->code_base());
   67.22 +    st->print_cr(" - code end (excl):   " INTPTR_FORMAT, m->code_base() + m->code_size());
   67.23 +  }
   67.24    if (m->method_data() != NULL) {
   67.25      st->print_cr(" - method data:       " INTPTR_FORMAT, (address)m->method_data());
   67.26    }
   67.27 @@ -293,6 +298,10 @@
   67.28      m->code()->print_value_on(st);
   67.29      st->cr();
   67.30    }
   67.31 +  if (m->is_native()) {
   67.32 +    st->print_cr(" - native function:   " INTPTR_FORMAT, m->native_function());
   67.33 +    st->print_cr(" - signature handler: " INTPTR_FORMAT, m->signature_handler());
   67.34 +  }
   67.35  }
   67.36  
   67.37  
    68.1 --- a/src/share/vm/oops/objArrayKlass.cpp	Wed Apr 01 22:31:26 2009 -0700
    68.2 +++ b/src/share/vm/oops/objArrayKlass.cpp	Thu Apr 02 17:01:00 2009 -0700
    68.3 @@ -1,5 +1,5 @@
    68.4  /*
    68.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    68.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    68.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    68.8   *
    68.9   * This code is free software; you can redistribute it and/or modify it
   68.10 @@ -502,12 +502,25 @@
   68.11    }
   68.12  }
   68.13  
   68.14 +static int max_objArray_print_length = 4;
   68.15  
   68.16  void objArrayKlass::oop_print_value_on(oop obj, outputStream* st) {
   68.17    assert(obj->is_objArray(), "must be objArray");
   68.18 +  st->print("a ");
   68.19    element_klass()->print_value_on(st);
   68.20 -  st->print("a [%d] ", objArrayOop(obj)->length());
   68.21 -  as_klassOop()->klass()->print_value_on(st);
   68.22 +  int len = objArrayOop(obj)->length();
   68.23 +  st->print("[%d] ", len);
   68.24 +  obj->print_address_on(st);
   68.25 +  if (PrintOopAddress || PrintMiscellaneous && (WizardMode || Verbose)) {
   68.26 +    st->print("{");
   68.27 +    for (int i = 0; i < len; i++) {
   68.28 +      if (i > max_objArray_print_length) {
   68.29 +        st->print("..."); break;
   68.30 +      }
   68.31 +      st->print(" "INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
   68.32 +    }
   68.33 +    st->print(" }");
   68.34 +  }
   68.35  }
   68.36  
   68.37  #endif // PRODUCT
    69.1 --- a/src/share/vm/oops/oop.cpp	Wed Apr 01 22:31:26 2009 -0700
    69.2 +++ b/src/share/vm/oops/oop.cpp	Thu Apr 02 17:01:00 2009 -0700
    69.3 @@ -1,5 +1,5 @@
    69.4  /*
    69.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    69.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    69.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    69.8   *
    69.9   * This code is free software; you can redistribute it and/or modify it
   69.10 @@ -65,11 +65,7 @@
   69.11  
   69.12  void oopDesc::print_address_on(outputStream* st) const {
   69.13    if (PrintOopAddress) {
   69.14 -    st->print("{");
   69.15 -    if (PrintOopAddress) {
   69.16 -      st->print(INTPTR_FORMAT, this);
   69.17 -    }
   69.18 -    st->print("}");
   69.19 +    st->print("{"INTPTR_FORMAT"}", this);
   69.20    }
   69.21  }
   69.22  
    70.1 --- a/src/share/vm/opto/block.hpp	Wed Apr 01 22:31:26 2009 -0700
    70.2 +++ b/src/share/vm/opto/block.hpp	Thu Apr 02 17:01:00 2009 -0700
    70.3 @@ -371,6 +371,7 @@
    70.4    Block *_broot;                // Basic block of root
    70.5    uint _rpo_ctr;
    70.6    CFGLoop* _root_loop;
    70.7 +  float _outer_loop_freq;       // Outmost loop frequency
    70.8  
    70.9    // Per node latency estimation, valid only during GCM
   70.10    GrowableArray<uint> _node_latency;
   70.11 @@ -537,6 +538,7 @@
   70.12    void compute_loop_depth(int depth);
   70.13    void compute_freq(); // compute frequency with loop assuming head freq 1.0f
   70.14    void scale_freq();   // scale frequency by loop trip count (including outer loops)
   70.15 +  float outer_loop_freq() const; // frequency of outer loop
   70.16    bool in_loop_nest(Block* b);
   70.17    float trip_count() const { return 1.0f / _exit_prob; }
   70.18    virtual bool is_loop()  { return true; }
    71.1 --- a/src/share/vm/opto/bytecodeInfo.cpp	Wed Apr 01 22:31:26 2009 -0700
    71.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp	Thu Apr 02 17:01:00 2009 -0700
    71.3 @@ -232,6 +232,14 @@
    71.4      return "disallowed by CompilerOracle";
    71.5    }
    71.6  
    71.7 +  if (UseStringCache) {
    71.8 +    // Do not inline StringCache::profile() method used only at the beginning.
    71.9 +    if (callee_method->name() == ciSymbol::profile_name() &&
   71.10 +        callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
   71.11 +      return "profiling method";
   71.12 +    }
   71.13 +  }
   71.14 +
   71.15    return NULL;
   71.16  }
   71.17  
    72.1 --- a/src/share/vm/opto/c2_globals.hpp	Wed Apr 01 22:31:26 2009 -0700
    72.2 +++ b/src/share/vm/opto/c2_globals.hpp	Thu Apr 02 17:01:00 2009 -0700
    72.3 @@ -391,7 +391,7 @@
    72.4    product(intx, EliminateAllocationArraySizeLimit, 64,                      \
    72.5            "Array size (number of elements) limit for scalar replacement")   \
    72.6                                                                              \
    72.7 -  product(bool, UseOptoBiasInlining, true,                                 \
    72.8 +  product(bool, UseOptoBiasInlining, true,                                  \
    72.9            "Generate biased locking code in C2 ideal graph")                 \
   72.10                                                                              \
   72.11    product(intx, ValueSearchLimit, 1000,                                     \
   72.12 @@ -410,7 +410,7 @@
   72.13            "Miniumum %% of a successor (predecessor) for which block layout "\
   72.14            "a will allow a fork (join) in a single chain")                   \
   72.15                                                                              \
   72.16 -  product(bool, BlockLayoutRotateLoops, false,                              \
   72.17 +  product(bool, BlockLayoutRotateLoops, true,                               \
   72.18            "Allow back branches to be fall throughs in the block layour")    \
   72.19  
   72.20  C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
    73.1 --- a/src/share/vm/opto/chaitin.cpp	Wed Apr 01 22:31:26 2009 -0700
    73.2 +++ b/src/share/vm/opto/chaitin.cpp	Thu Apr 02 17:01:00 2009 -0700
    73.3 @@ -149,6 +149,9 @@
    73.4  #endif
    73.5  {
    73.6    NOT_PRODUCT( Compile::TracePhase t3("ctorChaitin", &_t_ctorChaitin, TimeCompiler); )
    73.7 +
    73.8 +  _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg._outer_loop_freq);
    73.9 +
   73.10    uint i,j;
   73.11    // Build a list of basic blocks, sorted by frequency
   73.12    _blks = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
    74.1 --- a/src/share/vm/opto/chaitin.hpp	Wed Apr 01 22:31:26 2009 -0700
    74.2 +++ b/src/share/vm/opto/chaitin.hpp	Thu Apr 02 17:01:00 2009 -0700
    74.3 @@ -338,6 +338,8 @@
    74.4  
    74.5    Block **_blks;                // Array of blocks sorted by frequency for coalescing
    74.6  
    74.7 +  float _high_frequency_lrg;    // Frequency at which LRG will be spilled for debug info
    74.8 +
    74.9  #ifndef PRODUCT
   74.10    bool _trace_spilling;
   74.11  #endif
   74.12 @@ -360,6 +362,8 @@
   74.13  
   74.14    uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
   74.15  
   74.16 +  float high_frequency_lrg() const { return _high_frequency_lrg; }
   74.17 +
   74.18  #ifndef PRODUCT
   74.19    bool trace_spilling() const { return _trace_spilling; }
   74.20  #endif
    75.1 --- a/src/share/vm/opto/classes.hpp	Wed Apr 01 22:31:26 2009 -0700
    75.2 +++ b/src/share/vm/opto/classes.hpp	Thu Apr 02 17:01:00 2009 -0700
    75.3 @@ -218,6 +218,8 @@
    75.4  macro(StoreP)
    75.5  macro(StoreN)
    75.6  macro(StrComp)
    75.7 +macro(StrEquals)
    75.8 +macro(StrIndexOf)
    75.9  macro(SubD)
   75.10  macro(SubF)
   75.11  macro(SubI)
    76.1 --- a/src/share/vm/opto/coalesce.cpp	Wed Apr 01 22:31:26 2009 -0700
    76.2 +++ b/src/share/vm/opto/coalesce.cpp	Thu Apr 02 17:01:00 2009 -0700
    76.3 @@ -473,7 +473,7 @@
    76.4          } // End of is two-adr
    76.5  
    76.6          // Insert a copy at a debug use for a lrg which has high frequency
    76.7 -        if( (b->_freq < OPTO_DEBUG_SPLIT_FREQ) && n->is_MachSafePoint() ) {
    76.8 +        if( b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs) ) {
    76.9            // Walk the debug inputs to the node and check for lrg freq
   76.10            JVMState* jvms = n->jvms();
   76.11            uint debug_start = jvms ? jvms->debug_start() : 999999;
   76.12 @@ -487,7 +487,7 @@
   76.13              LRG &lrg = lrgs(nidx);
   76.14  
   76.15              // If this lrg has a high frequency use/def
   76.16 -            if( lrg._maxfreq >= OPTO_LRG_HIGH_FREQ ) {
   76.17 +            if( lrg._maxfreq >= _phc.high_frequency_lrg() ) {
   76.18                // If the live range is also live out of this block (like it
   76.19                // would be for a fast/slow idiom), the normal spill mechanism
   76.20                // does an excellent job.  If it is not live out of this block
    77.1 --- a/src/share/vm/opto/gcm.cpp	Wed Apr 01 22:31:26 2009 -0700
    77.2 +++ b/src/share/vm/opto/gcm.cpp	Thu Apr 02 17:01:00 2009 -0700
    77.3 @@ -438,6 +438,12 @@
    77.4  #endif
    77.5    assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrComp),
    77.6           "String compare is only known 'load' that does not conflict with any stores");
    77.7 +  assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrEquals),
    77.8 +         "String equals is a 'load' that does not conflict with any stores");
    77.9 +  assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrIndexOf),
   77.10 +         "String indexOf is a 'load' that does not conflict with any stores");
   77.11 +  assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_AryEq),
   77.12 +         "Arrays equals is a 'load' that do not conflict with any stores");
   77.13  
   77.14    if (!C->alias_type(load_alias_idx)->is_rewritable()) {
   77.15      // It is impossible to spoil this load by putting stores before it,
   77.16 @@ -1374,6 +1380,9 @@
   77.17    _root_loop->_freq = 1.0;
   77.18    _root_loop->scale_freq();
   77.19  
   77.20 +  // Save outmost loop frequency for LRG frequency threshold
   77.21 +  _outer_loop_freq = _root_loop->outer_loop_freq();
   77.22 +
   77.23    // force paths ending at uncommon traps to be infrequent
   77.24    if (!C->do_freq_based_layout()) {
   77.25      Block_List worklist;
   77.26 @@ -1898,6 +1907,7 @@
   77.27  // Do a top down traversal of loop tree (visit outer loops first.)
   77.28  void CFGLoop::scale_freq() {
   77.29    float loop_freq = _freq * trip_count();
   77.30 +  _freq = loop_freq;
   77.31    for (int i = 0; i < _members.length(); i++) {
   77.32      CFGElement* s = _members.at(i);
   77.33      float block_freq = s->_freq * loop_freq;
   77.34 @@ -1912,6 +1922,14 @@
   77.35    }
   77.36  }
   77.37  
   77.38 +// Frequency of outer loop
   77.39 +float CFGLoop::outer_loop_freq() const {
   77.40 +  if (_child != NULL) {
   77.41 +    return _child->_freq;
   77.42 +  }
   77.43 +  return _freq;
   77.44 +}
   77.45 +
   77.46  #ifndef PRODUCT
   77.47  //------------------------------dump_tree--------------------------------------
   77.48  void CFGLoop::dump_tree() const {
    78.1 --- a/src/share/vm/opto/lcm.cpp	Wed Apr 01 22:31:26 2009 -0700
    78.2 +++ b/src/share/vm/opto/lcm.cpp	Thu Apr 02 17:01:00 2009 -0700
    78.3 @@ -137,6 +137,8 @@
    78.4        if( mach->in(2) != val ) continue;
    78.5        break;                    // Found a memory op?
    78.6      case Op_StrComp:
    78.7 +    case Op_StrEquals:
    78.8 +    case Op_StrIndexOf:
    78.9      case Op_AryEq:
   78.10        // Not a legit memory op for implicit null check regardless of
   78.11        // embedded loads
    79.1 --- a/src/share/vm/opto/library_call.cpp	Wed Apr 01 22:31:26 2009 -0700
    79.2 +++ b/src/share/vm/opto/library_call.cpp	Thu Apr 02 17:01:00 2009 -0700
    79.3 @@ -136,6 +136,7 @@
    79.4    bool inline_string_compareTo();
    79.5    bool inline_string_indexOf();
    79.6    Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
    79.7 +  bool inline_string_equals();
    79.8    Node* pop_math_arg();
    79.9    bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
   79.10    bool inline_math_native(vmIntrinsics::ID id);
   79.11 @@ -261,6 +262,7 @@
   79.12      switch (id) {
   79.13      case vmIntrinsics::_indexOf:
   79.14      case vmIntrinsics::_compareTo:
   79.15 +    case vmIntrinsics::_equals:
   79.16      case vmIntrinsics::_equalsC:
   79.17        break;  // InlineNatives does not control String.compareTo
   79.18      default:
   79.19 @@ -275,6 +277,9 @@
   79.20    case vmIntrinsics::_indexOf:
   79.21      if (!SpecialStringIndexOf)  return NULL;
   79.22      break;
   79.23 +  case vmIntrinsics::_equals:
   79.24 +    if (!SpecialStringEquals)  return NULL;
   79.25 +    break;
   79.26    case vmIntrinsics::_equalsC:
   79.27      if (!SpecialArraysEquals)  return NULL;
   79.28      break;
   79.29 @@ -442,6 +447,8 @@
   79.30      return inline_string_compareTo();
   79.31    case vmIntrinsics::_indexOf:
   79.32      return inline_string_indexOf();
   79.33 +  case vmIntrinsics::_equals:
   79.34 +    return inline_string_equals();
   79.35  
   79.36    case vmIntrinsics::_getObject:
   79.37      return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, false);
   79.38 @@ -793,6 +800,8 @@
   79.39  //------------------------------inline_string_compareTo------------------------
   79.40  bool LibraryCallKit::inline_string_compareTo() {
   79.41  
   79.42 +  if (!Matcher::has_match_rule(Op_StrComp)) return false;
   79.43 +
   79.44    const int value_offset = java_lang_String::value_offset_in_bytes();
   79.45    const int count_offset = java_lang_String::count_offset_in_bytes();
   79.46    const int offset_offset = java_lang_String::offset_offset_in_bytes();
   79.47 @@ -830,6 +839,82 @@
   79.48    return true;
   79.49  }
   79.50  
   79.51 +//------------------------------inline_string_equals------------------------
   79.52 +bool LibraryCallKit::inline_string_equals() {
   79.53 +
   79.54 +  if (!Matcher::has_match_rule(Op_StrEquals)) return false;
   79.55 +
   79.56 +  const int value_offset = java_lang_String::value_offset_in_bytes();
   79.57 +  const int count_offset = java_lang_String::count_offset_in_bytes();
   79.58 +  const int offset_offset = java_lang_String::offset_offset_in_bytes();
   79.59 +
   79.60 +  _sp += 2;
   79.61 +  Node* argument = pop();  // pop non-receiver first:  it was pushed second
   79.62 +  Node* receiver = pop();
   79.63 +
   79.64 +  // Null check on self without removing any arguments.  The argument
   79.65 +  // null check technically happens in the wrong place, which can lead to
   79.66 +  // invalid stack traces when string compare is inlined into a method
   79.67 +  // which handles NullPointerExceptions.
   79.68 +  _sp += 2;
   79.69 +  receiver = do_null_check(receiver, T_OBJECT);
   79.70 +  //should not do null check for argument for String.equals(), because spec
   79.71 +  //allows to specify NULL as argument.
   79.72 +  _sp -= 2;
   79.73 +
   79.74 +  if (stopped()) {
   79.75 +    return true;
   79.76 +  }
   79.77 +
   79.78 +  // get String klass for instanceOf
   79.79 +  ciInstanceKlass* klass = env()->String_klass();
   79.80 +
   79.81 +  // two paths (plus control) merge
   79.82 +  RegionNode* region = new (C, 3) RegionNode(3);
   79.83 +  Node* phi = new (C, 3) PhiNode(region, TypeInt::BOOL);
   79.84 +
   79.85 +  Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
   79.86 +  Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
   79.87 +  Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
   79.88 +
   79.89 +  IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
   79.90 +
   79.91 +  Node* if_true  = _gvn.transform(new (C, 1) IfTrueNode(iff));
   79.92 +  set_control(if_true);
   79.93 +
   79.94 +  const TypeInstPtr* string_type =
   79.95 +    TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
   79.96 +
   79.97 +  // instanceOf == true
   79.98 +  Node* equals =
   79.99 +    _gvn.transform(new (C, 7) StrEqualsNode(
  79.100 +                        control(),
  79.101 +                        memory(TypeAryPtr::CHARS),
  79.102 +                        memory(string_type->add_offset(value_offset)),
  79.103 +                        memory(string_type->add_offset(count_offset)),
  79.104 +                        memory(string_type->add_offset(offset_offset)),
  79.105 +                        receiver,
  79.106 +                        argument));
  79.107 +
  79.108 +  phi->init_req(1, _gvn.transform(equals));
  79.109 +  region->init_req(1, if_true);
  79.110 +
  79.111 +  //instanceOf == false, fallthrough
  79.112 +  Node* if_false = _gvn.transform(new (C, 1) IfFalseNode(iff));
  79.113 +  set_control(if_false);
  79.114 +
  79.115 +  phi->init_req(2, _gvn.transform(intcon(0)));
  79.116 +  region->init_req(2, if_false);
  79.117 +
  79.118 +  // post merge
  79.119 +  set_control(_gvn.transform(region));
  79.120 +  record_for_igvn(region);
  79.121 +
  79.122 +  push(_gvn.transform(phi));
  79.123 +
  79.124 +  return true;
  79.125 +}
  79.126 +
  79.127  //------------------------------inline_array_equals----------------------------
  79.128  bool LibraryCallKit::inline_array_equals() {
  79.129  
  79.130 @@ -994,80 +1079,115 @@
  79.131    return result;
  79.132  }
  79.133  
  79.134 -
  79.135  //------------------------------inline_string_indexOf------------------------
  79.136  bool LibraryCallKit::inline_string_indexOf() {
  79.137  
  79.138 +  const int value_offset  = java_lang_String::value_offset_in_bytes();
  79.139 +  const int count_offset  = java_lang_String::count_offset_in_bytes();
  79.140 +  const int offset_offset = java_lang_String::offset_offset_in_bytes();
  79.141 +
  79.142    _sp += 2;
  79.143    Node *argument = pop();  // pop non-receiver first:  it was pushed second
  79.144    Node *receiver = pop();
  79.145  
  79.146 -  // don't intrinsify if argument isn't a constant string.
  79.147 -  if (!argument->is_Con()) {
  79.148 -    return false;
  79.149 +  Node* result;
  79.150 +  if (Matcher::has_match_rule(Op_StrIndexOf) &&
  79.151 +      UseSSE42Intrinsics) {
  79.152 +    // Generate SSE4.2 version of indexOf
  79.153 +    // We currently only have match rules that use SSE4.2
  79.154 +
  79.155 +    // Null check on self without removing any arguments.  The argument
  79.156 +    // null check technically happens in the wrong place, which can lead to
  79.157 +    // invalid stack traces when string compare is inlined into a method
  79.158 +    // which handles NullPointerExceptions.
  79.159 +    _sp += 2;
  79.160 +    receiver = do_null_check(receiver, T_OBJECT);
  79.161 +    argument = do_null_check(argument, T_OBJECT);
  79.162 +    _sp -= 2;
  79.163 +
  79.164 +    if (stopped()) {
  79.165 +      return true;
  79.166 +    }
  79.167 +
  79.168 +    ciInstanceKlass* klass = env()->String_klass();
  79.169 +    const TypeInstPtr* string_type =
  79.170 +      TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
  79.171 +
  79.172 +    result =
  79.173 +      _gvn.transform(new (C, 7)
  79.174 +                     StrIndexOfNode(control(),
  79.175 +                                    memory(TypeAryPtr::CHARS),
  79.176 +                                    memory(string_type->add_offset(value_offset)),
  79.177 +                                    memory(string_type->add_offset(count_offset)),
  79.178 +                                    memory(string_type->add_offset(offset_offset)),
  79.179 +                                    receiver,
  79.180 +                                    argument));
  79.181 +  } else { //Use LibraryCallKit::string_indexOf
  79.182 +    // don't intrinsify is argument isn't a constant string.
  79.183 +    if (!argument->is_Con()) {
  79.184 +     return false;
  79.185 +    }
  79.186 +    const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
  79.187 +    if (str_type == NULL) {
  79.188 +      return false;
  79.189 +    }
  79.190 +    ciInstanceKlass* klass = env()->String_klass();
  79.191 +    ciObject* str_const = str_type->const_oop();
  79.192 +    if (str_const == NULL || str_const->klass() != klass) {
  79.193 +      return false;
  79.194 +    }
  79.195 +    ciInstance* str = str_const->as_instance();
  79.196 +    assert(str != NULL, "must be instance");
  79.197 +
  79.198 +    ciObject* v = str->field_value_by_offset(value_offset).as_object();
  79.199 +    int       o = str->field_value_by_offset(offset_offset).as_int();
  79.200 +    int       c = str->field_value_by_offset(count_offset).as_int();
  79.201 +    ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
  79.202 +
  79.203 +    // constant strings have no offset and count == length which
  79.204 +    // simplifies the resulting code somewhat so lets optimize for that.
  79.205 +    if (o != 0 || c != pat->length()) {
  79.206 +     return false;
  79.207 +    }
  79.208 +
  79.209 +    // Null check on self without removing any arguments.  The argument
  79.210 +    // null check technically happens in the wrong place, which can lead to
  79.211 +    // invalid stack traces when string compare is inlined into a method
  79.212 +    // which handles NullPointerExceptions.
  79.213 +    _sp += 2;
  79.214 +    receiver = do_null_check(receiver, T_OBJECT);
  79.215 +    // No null check on the argument is needed since it's a constant String oop.
  79.216 +    _sp -= 2;
  79.217 +    if (stopped()) {
  79.218 +     return true;
  79.219 +    }
  79.220 +
  79.221 +    // The null string as a pattern always returns 0 (match at beginning of string)
  79.222 +    if (c == 0) {
  79.223 +      push(intcon(0));
  79.224 +      return true;
  79.225 +    }
  79.226 +
  79.227 +    // Generate default indexOf
  79.228 +    jchar lastChar = pat->char_at(o + (c - 1));
  79.229 +    int cache = 0;
  79.230 +    int i;
  79.231 +    for (i = 0; i < c - 1; i++) {
  79.232 +      assert(i < pat->length(), "out of range");
  79.233 +      cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
  79.234 +    }
  79.235 +
  79.236 +    int md2 = c;
  79.237 +    for (i = 0; i < c - 1; i++) {
  79.238 +      assert(i < pat->length(), "out of range");
  79.239 +      if (pat->char_at(o + i) == lastChar) {
  79.240 +        md2 = (c - 1) - i;
  79.241 +      }
  79.242 +    }
  79.243 +
  79.244 +    result = string_indexOf(receiver, pat, o, cache, md2);
  79.245    }
  79.246 -  const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
  79.247 -  if (str_type == NULL) {
  79.248 -    return false;
  79.249 -  }
  79.250 -  ciInstanceKlass* klass = env()->String_klass();
  79.251 -  ciObject* str_const = str_type->const_oop();
  79.252 -  if (str_const == NULL || str_const->klass() != klass) {
  79.253 -    return false;
  79.254 -  }
  79.255 -  ciInstance* str = str_const->as_instance();
  79.256 -  assert(str != NULL, "must be instance");
  79.257 -
  79.258 -  const int value_offset  = java_lang_String::value_offset_in_bytes();
  79.259 -  const int count_offset  = java_lang_String::count_offset_in_bytes();
  79.260 -  const int offset_offset = java_lang_String::offset_offset_in_bytes();
  79.261 -
  79.262 -  ciObject* v = str->field_value_by_offset(value_offset).as_object();
  79.263 -  int       o = str->field_value_by_offset(offset_offset).as_int();
  79.264 -  int       c = str->field_value_by_offset(count_offset).as_int();
  79.265 -  ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
  79.266 -
  79.267 -  // constant strings have no offset and count == length which
  79.268 -  // simplifies the resulting code somewhat so lets optimize for that.
  79.269 -  if (o != 0 || c != pat->length()) {
  79.270 -    return false;
  79.271 -  }
  79.272 -
  79.273 -  // Null check on self without removing any arguments.  The argument
  79.274 -  // null check technically happens in the wrong place, which can lead to
  79.275 -  // invalid stack traces when string compare is inlined into a method
  79.276 -  // which handles NullPointerExceptions.
  79.277 -  _sp += 2;
  79.278 -  receiver = do_null_check(receiver, T_OBJECT);
  79.279 -  // No null check on the argument is needed since it's a constant String oop.
  79.280 -  _sp -= 2;
  79.281 -  if (stopped()) {
  79.282 -    return true;
  79.283 -  }
  79.284 -
  79.285 -  // The null string as a pattern always returns 0 (match at beginning of string)
  79.286 -  if (c == 0) {
  79.287 -    push(intcon(0));
  79.288 -    return true;
  79.289 -  }
  79.290 -
  79.291 -  jchar lastChar = pat->char_at(o + (c - 1));
  79.292 -  int cache = 0;
  79.293 -  int i;
  79.294 -  for (i = 0; i < c - 1; i++) {
  79.295 -    assert(i < pat->length(), "out of range");
  79.296 -    cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
  79.297 -  }
  79.298 -
  79.299 -  int md2 = c;
  79.300 -  for (i = 0; i < c - 1; i++) {
  79.301 -    assert(i < pat->length(), "out of range");
  79.302 -    if (pat->char_at(o + i) == lastChar) {
  79.303 -      md2 = (c - 1) - i;
  79.304 -    }
  79.305 -  }
  79.306 -
  79.307 -  Node* result = string_indexOf(receiver, pat, o, cache, md2);
  79.308 +
  79.309    push(result);
  79.310    return true;
  79.311  }
    80.1 --- a/src/share/vm/opto/loopnode.cpp	Wed Apr 01 22:31:26 2009 -0700
    80.2 +++ b/src/share/vm/opto/loopnode.cpp	Thu Apr 02 17:01:00 2009 -0700
    80.3 @@ -2668,6 +2668,8 @@
    80.4      case Op_LoadD_unaligned:
    80.5      case Op_LoadL_unaligned:
    80.6      case Op_StrComp:            // Does a bunch of load-like effects
    80.7 +    case Op_StrEquals:
    80.8 +    case Op_StrIndexOf:
    80.9      case Op_AryEq:
   80.10        pinned = false;
   80.11      }
    81.1 --- a/src/share/vm/opto/machnode.cpp	Wed Apr 01 22:31:26 2009 -0700
    81.2 +++ b/src/share/vm/opto/machnode.cpp	Thu Apr 02 17:01:00 2009 -0700
    81.3 @@ -340,6 +340,10 @@
    81.4    if (base == NodeSentinel)  return TypePtr::BOTTOM;
    81.5  
    81.6    const Type* t = base->bottom_type();
    81.7 +  if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
    81.8 +    // 32-bit unscaled narrow oop can be the base of any address expression
    81.9 +    t = t->make_ptr();
   81.10 +  }
   81.11    if (t->isa_intptr_t() && offset != 0 && offset != Type::OffsetBot) {
   81.12      // We cannot assert that the offset does not look oop-ish here.
   81.13      // Depending on the heap layout the cardmark base could land
   81.14 @@ -353,6 +357,7 @@
   81.15  
   81.16    // be conservative if we do not recognize the type
   81.17    if (tp == NULL) {
   81.18 +    assert(false, "this path may produce not optimal code");
   81.19      return TypePtr::BOTTOM;
   81.20    }
   81.21    assert(tp->base() != Type::AnyPtr, "not a bare pointer");
    82.1 --- a/src/share/vm/opto/matcher.cpp	Wed Apr 01 22:31:26 2009 -0700
    82.2 +++ b/src/share/vm/opto/matcher.cpp	Thu Apr 02 17:01:00 2009 -0700
    82.3 @@ -746,6 +746,8 @@
    82.4    if (nidx == Compile::AliasIdxBot && midx == Compile::AliasIdxTop) {
    82.5      switch (n->Opcode()) {
    82.6      case Op_StrComp:
    82.7 +    case Op_StrEquals:
    82.8 +    case Op_StrIndexOf:
    82.9      case Op_AryEq:
   82.10      case Op_MemBarVolatile:
   82.11      case Op_MemBarCPUOrder: // %%% these ideals should have narrower adr_type?
   82.12 @@ -1788,6 +1790,8 @@
   82.13          mstack.push(n->in(0), Pre_Visit);     // Visit Control input
   82.14          continue;                             // while (mstack.is_nonempty())
   82.15        case Op_StrComp:
   82.16 +      case Op_StrEquals:
   82.17 +      case Op_StrIndexOf:
   82.18        case Op_AryEq:
   82.19          set_shared(n); // Force result into register (it will be anyways)
   82.20          break;
    83.1 --- a/src/share/vm/opto/memnode.cpp	Wed Apr 01 22:31:26 2009 -0700
    83.2 +++ b/src/share/vm/opto/memnode.cpp	Thu Apr 02 17:01:00 2009 -0700
    83.3 @@ -2481,6 +2481,31 @@
    83.4    return remove_dead_region(phase, can_reshape) ? this : NULL;
    83.5  }
    83.6  
    83.7 +// Do we match on this edge? No memory edges
    83.8 +uint StrEqualsNode::match_edge(uint idx) const {
    83.9 +  return idx == 5 || idx == 6;
   83.10 +}
   83.11 +
   83.12 +//------------------------------Ideal------------------------------------------
   83.13 +// Return a node which is more "ideal" than the current node.  Strip out
   83.14 +// control copies
   83.15 +Node *StrEqualsNode::Ideal(PhaseGVN *phase, bool can_reshape){
   83.16 +  return remove_dead_region(phase, can_reshape) ? this : NULL;
   83.17 +}
   83.18 +
   83.19 +//=============================================================================
   83.20 +// Do we match on this edge? No memory edges
   83.21 +uint StrIndexOfNode::match_edge(uint idx) const {
   83.22 +  return idx == 5 || idx == 6;
   83.23 +}
   83.24 +
   83.25 +//------------------------------Ideal------------------------------------------
   83.26 +// Return a node which is more "ideal" than the current node.  Strip out
   83.27 +// control copies
   83.28 +Node *StrIndexOfNode::Ideal(PhaseGVN *phase, bool can_reshape){
   83.29 +  return remove_dead_region(phase, can_reshape) ? this : NULL;
   83.30 +}
   83.31 +
   83.32  //------------------------------Ideal------------------------------------------
   83.33  // Return a node which is more "ideal" than the current node.  Strip out
   83.34  // control copies
   83.35 @@ -2488,7 +2513,6 @@
   83.36    return remove_dead_region(phase, can_reshape) ? this : NULL;
   83.37  }
   83.38  
   83.39 -
   83.40  //=============================================================================
   83.41  MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent)
   83.42    : MultiNode(TypeFunc::Parms + (precedent == NULL? 0: 1)),
    84.1 --- a/src/share/vm/opto/memnode.hpp	Wed Apr 01 22:31:26 2009 -0700
    84.2 +++ b/src/share/vm/opto/memnode.hpp	Thu Apr 02 17:01:00 2009 -0700
    84.3 @@ -765,6 +765,54 @@
    84.4    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    84.5  };
    84.6  
    84.7 +//------------------------------StrEquals-------------------------------------
    84.8 +class StrEqualsNode: public Node {
    84.9 +public:
   84.10 +  StrEqualsNode(Node *control,
   84.11 +                Node* char_array_mem,
   84.12 +                Node* value_mem,
   84.13 +                Node* count_mem,
   84.14 +                Node* offset_mem,
   84.15 +                Node* s1, Node* s2): Node(control,
   84.16 +                                          char_array_mem,
   84.17 +                                          value_mem,
   84.18 +                                          count_mem,
   84.19 +                                          offset_mem,
   84.20 +                                          s1, s2) {};
   84.21 +  virtual int Opcode() const;
   84.22 +  virtual bool depends_only_on_test() const { return false; }
   84.23 +  virtual const Type* bottom_type() const { return TypeInt::BOOL; }
   84.24 +  // a StrEqualsNode (conservatively) aliases with everything:
   84.25 +  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
   84.26 +  virtual uint match_edge(uint idx) const;
   84.27 +  virtual uint ideal_reg() const { return Op_RegI; }
   84.28 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   84.29 +};
   84.30 +
   84.31 +//------------------------------StrIndexOf-------------------------------------
   84.32 +class StrIndexOfNode: public Node {
   84.33 +public:
   84.34 +  StrIndexOfNode(Node *control,
   84.35 +                 Node* char_array_mem,
   84.36 +                 Node* value_mem,
   84.37 +                 Node* count_mem,
   84.38 +                 Node* offset_mem,
   84.39 +                 Node* s1, Node* s2): Node(control,
   84.40 +                                           char_array_mem,
   84.41 +                                           value_mem,
   84.42 +                                           count_mem,
   84.43 +                                           offset_mem,
   84.44 +                                           s1, s2) {};
   84.45 +  virtual int Opcode() const;
   84.46 +  virtual bool depends_only_on_test() const { return false; }
   84.47 +  virtual const Type* bottom_type() const { return TypeInt::INT; }
   84.48 +  // a StrIndexOfNode (conservatively) aliases with everything:
   84.49 +  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
   84.50 +  virtual uint match_edge(uint idx) const;
   84.51 +  virtual uint ideal_reg() const { return Op_RegI; }
   84.52 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   84.53 +};
   84.54 +
   84.55  //------------------------------AryEq---------------------------------------
   84.56  class AryEqNode: public Node {
   84.57  public:
    85.1 --- a/src/share/vm/opto/parse1.cpp	Wed Apr 01 22:31:26 2009 -0700
    85.2 +++ b/src/share/vm/opto/parse1.cpp	Thu Apr 02 17:01:00 2009 -0700
    85.3 @@ -95,7 +95,7 @@
    85.4    switch( bt ) {                // Signature is flattened
    85.5    case T_INT:     l = new (C, 3) LoadINode( 0, mem, adr, TypeRawPtr::BOTTOM ); break;
    85.6    case T_FLOAT:   l = new (C, 3) LoadFNode( 0, mem, adr, TypeRawPtr::BOTTOM ); break;
    85.7 -  case T_ADDRESS:
    85.8 +  case T_ADDRESS: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM  ); break;
    85.9    case T_OBJECT:  l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
   85.10    case T_LONG:
   85.11    case T_DOUBLE: {
    86.1 --- a/src/share/vm/opto/subnode.cpp	Wed Apr 01 22:31:26 2009 -0700
    86.2 +++ b/src/share/vm/opto/subnode.cpp	Thu Apr 02 17:01:00 2009 -0700
    86.3 @@ -639,8 +639,8 @@
    86.4      int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
    86.5      if (klass0 && klass1 &&
    86.6          kps != 1 &&             // both or neither are klass pointers
    86.7 -        !klass0->is_interface() && // do not trust interfaces
    86.8 -        !klass1->is_interface()) {
    86.9 +        klass0->is_loaded() && !klass0->is_interface() && // do not trust interfaces
   86.10 +        klass1->is_loaded() && !klass1->is_interface()) {
   86.11        bool unrelated_classes = false;
   86.12        // See if neither subclasses the other, or if the class on top
   86.13        // is precise.  In either of these cases, the compare is known
    87.1 --- a/src/share/vm/opto/superword.cpp	Wed Apr 01 22:31:26 2009 -0700
    87.2 +++ b/src/share/vm/opto/superword.cpp	Thu Apr 02 17:01:00 2009 -0700
    87.3 @@ -454,9 +454,13 @@
    87.4            // or need to run igvn.optimize() again before SLP
    87.5          } else if (out->is_Phi() && out->bottom_type() == Type::MEMORY && !in_bb(out)) {
    87.6            // Ditto.  Not sure what else to check further.
    87.7 -        } else if (out->Opcode() == Op_StoreCM && out->in(4) == n) {
    87.8 +        } else if (out->Opcode() == Op_StoreCM && out->in(MemNode::OopStore) == n) {
    87.9            // StoreCM has an input edge used as a precedence edge.
   87.10            // Maybe an issue when oop stores are vectorized.
   87.11 +        } else if( out->is_MergeMem() && prev &&
   87.12 +                   prev->Opcode() == Op_StoreCM && out == prev->in(MemNode::OopStore)) {
   87.13 +          // Oop store is a MergeMem! This should not happen. Temporarily remove the assertion
   87.14 +          // for this case because it could not be superwordized anyway.
   87.15          } else {
   87.16            assert(out == prev || prev == NULL, "no branches off of store slice");
   87.17          }
   87.18 @@ -912,54 +916,175 @@
   87.19    }
   87.20  }
   87.21  
   87.22 -//------------------------------co_locate_pack---------------------------
   87.23 -// Within a pack, move stores down to the last executed store,
   87.24 -// and move loads up to the first executed load.
   87.25 +//-------------------------------remove_and_insert-------------------
   87.26 +//remove "current" from its current position in the memory graph and insert
   87.27 +//it after the appropriate insertion point (lip or uip)
   87.28 +void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
   87.29 +                                  Node *uip, Unique_Node_List &sched_before) {
   87.30 +  Node* my_mem = current->in(MemNode::Memory);
   87.31 +  _igvn.hash_delete(current);
   87.32 +  _igvn.hash_delete(my_mem);
   87.33 +
   87.34 +  //remove current_store from its current position in the memmory graph
   87.35 +  for (DUIterator i = current->outs(); current->has_out(i); i++) {
   87.36 +    Node* use = current->out(i);
   87.37 +    if (use->is_Mem()) {
   87.38 +      assert(use->in(MemNode::Memory) == current, "must be");
   87.39 +      _igvn.hash_delete(use);
   87.40 +      if (use == prev) { // connect prev to my_mem
   87.41 +        use->set_req(MemNode::Memory, my_mem);
   87.42 +      } else if (sched_before.member(use)) {
   87.43 +        _igvn.hash_delete(uip);
   87.44 +        use->set_req(MemNode::Memory, uip);
   87.45 +      } else {
   87.46 +        _igvn.hash_delete(lip);
   87.47 +        use->set_req(MemNode::Memory, lip);
   87.48 +      }
   87.49 +      _igvn._worklist.push(use);
   87.50 +      --i; //deleted this edge; rescan position
   87.51 +    }
   87.52 +  }
   87.53 +
   87.54 +  bool sched_up = sched_before.member(current);
   87.55 +  Node *insert_pt =  sched_up ?  uip : lip;
   87.56 +  _igvn.hash_delete(insert_pt);
   87.57 +
   87.58 +  // all uses of insert_pt's memory state should use current's instead
   87.59 +  for (DUIterator i = insert_pt->outs(); insert_pt->has_out(i); i++) {
   87.60 +    Node* use = insert_pt->out(i);
   87.61 +    if (use->is_Mem()) {
   87.62 +      assert(use->in(MemNode::Memory) == insert_pt, "must be");
   87.63 +      _igvn.hash_delete(use);
   87.64 +      use->set_req(MemNode::Memory, current);
   87.65 +      _igvn._worklist.push(use);
   87.66 +      --i; //deleted this edge; rescan position
   87.67 +    } else if (!sched_up && use->is_Phi() && use->bottom_type() == Type::MEMORY) {
   87.68 +      uint pos; //lip (lower insert point) must be the last one in the memory slice
   87.69 +      _igvn.hash_delete(use);
   87.70 +      for (pos=1; pos < use->req(); pos++) {
   87.71 +        if (use->in(pos) == insert_pt) break;
   87.72 +      }
   87.73 +      use->set_req(pos, current);
   87.74 +      _igvn._worklist.push(use);
   87.75 +      --i;
   87.76 +    }
   87.77 +  }
   87.78 +
   87.79 +  //connect current to insert_pt
   87.80 +  current->set_req(MemNode::Memory, insert_pt);
   87.81 +  _igvn._worklist.push(current);
   87.82 +}
   87.83 +
   87.84 +//------------------------------co_locate_pack----------------------------------
   87.85 +// To schedule a store pack, we need to move any sandwiched memory ops either before
   87.86 +// or after the pack, based upon dependence information:
   87.87 +// (1) If any store in the pack depends on the sandwiched memory op, the
   87.88 +//     sandwiched memory op must be scheduled BEFORE the pack;
   87.89 +// (2) If a sandwiched memory op depends on any store in the pack, the
   87.90 +//     sandwiched memory op must be scheduled AFTER the pack;
   87.91 +// (3) If a sandwiched memory op (say, memA) depends on another sandwiched
   87.92 +//     memory op (say memB), memB must be scheduled before memA. So, if memA is
   87.93 +//     scheduled before the pack, memB must also be scheduled before the pack;
   87.94 +// (4) If there is no dependence restriction for a sandwiched memory op, we simply
   87.95 +//     schedule this store AFTER the pack
   87.96 +// (5) We know there is no dependence cycle, so there in no other case;
   87.97 +// (6) Finally, all memory ops in another single pack should be moved in the same direction.
   87.98 +//
   87.99 +// To schedule a load pack: the memory edge of every loads in the pack must be
  87.100 +// the same as the memory edge of the last executed load in the pack
  87.101  void SuperWord::co_locate_pack(Node_List* pk) {
  87.102    if (pk->at(0)->is_Store()) {
  87.103 -    // Push Stores down towards last executed pack member
  87.104      MemNode* first     = executed_first(pk)->as_Mem();
  87.105      MemNode* last      = executed_last(pk)->as_Mem();
  87.106 -    MemNode* insert_pt = last;
  87.107 +    Unique_Node_List schedule_before_pack;
  87.108 +    Unique_Node_List memops;
  87.109 +
  87.110      MemNode* current   = last->in(MemNode::Memory)->as_Mem();
  87.111 +    MemNode* previous  = last;
  87.112      while (true) {
  87.113        assert(in_bb(current), "stay in block");
  87.114 +      memops.push(previous);
  87.115 +      for (DUIterator i = current->outs(); current->has_out(i); i++) {
  87.116 +        Node* use = current->out(i);
  87.117 +        if (use->is_Mem() && use != previous)
  87.118 +          memops.push(use);
  87.119 +      }
  87.120 +      if(current == first) break;
  87.121 +      previous = current;
  87.122 +      current  = current->in(MemNode::Memory)->as_Mem();
  87.123 +    }
  87.124 +
  87.125 +    // determine which memory operations should be scheduled before the pack
  87.126 +    for (uint i = 1; i < memops.size(); i++) {
  87.127 +      Node *s1 = memops.at(i);
  87.128 +      if (!in_pack(s1, pk) && !schedule_before_pack.member(s1)) {
  87.129 +        for (uint j = 0; j< i; j++) {
  87.130 +          Node *s2 = memops.at(j);
  87.131 +          if (!independent(s1, s2)) {
  87.132 +            if (in_pack(s2, pk) || schedule_before_pack.member(s2)) {
  87.133 +              schedule_before_pack.push(s1); //s1 must be scheduled before
  87.134 +              Node_List* mem_pk = my_pack(s1);
  87.135 +              if (mem_pk != NULL) {
  87.136 +                for (uint ii = 0; ii < mem_pk->size(); ii++) {
  87.137 +                  Node* s = mem_pk->at(ii); // follow partner
  87.138 +                  if (memops.member(s) && !schedule_before_pack.member(s))
  87.139 +                    schedule_before_pack.push(s);
  87.140 +                }
  87.141 +              }
  87.142 +            }
  87.143 +          }
  87.144 +        }
  87.145 +      }
  87.146 +    }
  87.147 +
  87.148 +    MemNode* lower_insert_pt = last;
  87.149 +    Node*    upper_insert_pt = first->in(MemNode::Memory);
  87.150 +    previous                 = last; //previous store in pk
  87.151 +    current                  = last->in(MemNode::Memory)->as_Mem();
  87.152 +
  87.153 +    //start scheduling from "last" to "first"
  87.154 +    while (true) {
  87.155 +      assert(in_bb(current), "stay in block");
  87.156 +      assert(in_pack(previous, pk), "previous stays in pack");
  87.157        Node* my_mem = current->in(MemNode::Memory);
  87.158 +
  87.159        if (in_pack(current, pk)) {
  87.160 -        // Forward users of my memory state to my input memory state
  87.161 +        // Forward users of my memory state (except "previous) to my input memory state
  87.162          _igvn.hash_delete(current);
  87.163 -        _igvn.hash_delete(my_mem);
  87.164          for (DUIterator i = current->outs(); current->has_out(i); i++) {
  87.165            Node* use = current->out(i);
  87.166 -          if (use->is_Mem()) {
  87.167 +          if (use->is_Mem() && use != previous) {
  87.168              assert(use->in(MemNode::Memory) == current, "must be");
  87.169              _igvn.hash_delete(use);
  87.170 -            use->set_req(MemNode::Memory, my_mem);
  87.171 +            if (schedule_before_pack.member(use)) {
  87.172 +              _igvn.hash_delete(upper_insert_pt);
  87.173 +              use->set_req(MemNode::Memory, upper_insert_pt);
  87.174 +            } else {
  87.175 +              _igvn.hash_delete(lower_insert_pt);
  87.176 +              use->set_req(MemNode::Memory, lower_insert_pt);
  87.177 +            }
  87.178              _igvn._worklist.push(use);
  87.179              --i; // deleted this edge; rescan position
  87.180            }
  87.181          }
  87.182 -        // put current immediately before insert_pt
  87.183 -        current->set_req(MemNode::Memory, insert_pt->in(MemNode::Memory));
  87.184 -        _igvn.hash_delete(insert_pt);
  87.185 -        insert_pt->set_req(MemNode::Memory, current);
  87.186 -        _igvn._worklist.push(insert_pt);
  87.187 -        _igvn._worklist.push(current);
  87.188 -        insert_pt = current;
  87.189 +        previous = current;
  87.190 +      } else { // !in_pack(current, pk) ==> a sandwiched store
  87.191 +        remove_and_insert(current, previous, lower_insert_pt, upper_insert_pt, schedule_before_pack);
  87.192        }
  87.193 +
  87.194        if (current == first) break;
  87.195        current = my_mem->as_Mem();
  87.196 -    }
  87.197 -  } else if (pk->at(0)->is_Load()) {
  87.198 -    // Pull Loads up towards first executed pack member
  87.199 -    LoadNode* first = executed_first(pk)->as_Load();
  87.200 -    Node* first_mem = first->in(MemNode::Memory);
  87.201 -    _igvn.hash_delete(first_mem);
  87.202 -    // Give each load same memory state as first
  87.203 +    } // end while
  87.204 +  } else if (pk->at(0)->is_Load()) { //load
  87.205 +    // all use the memory state that the last executed load uses
  87.206 +    LoadNode* last_load  = executed_last(pk)->as_Load();
  87.207 +    Node* last_mem       = last_load->in(MemNode::Memory);
  87.208 +    _igvn.hash_delete(last_mem);
  87.209 +    // Give each load same memory state as last
  87.210      for (uint i = 0; i < pk->size(); i++) {
  87.211        LoadNode* ld = pk->at(i)->as_Load();
  87.212        _igvn.hash_delete(ld);
  87.213 -      ld->set_req(MemNode::Memory, first_mem);
  87.214 +      ld->set_req(MemNode::Memory, last_mem);
  87.215        _igvn._worklist.push(ld);
  87.216      }
  87.217    }
    88.1 --- a/src/share/vm/opto/superword.hpp	Wed Apr 01 22:31:26 2009 -0700
    88.2 +++ b/src/share/vm/opto/superword.hpp	Thu Apr 02 17:01:00 2009 -0700
    88.3 @@ -341,8 +341,11 @@
    88.4    void filter_packs();
    88.5    // Adjust the memory graph for the packed operations
    88.6    void schedule();
    88.7 -  // Within a pack, move stores down to the last executed store,
    88.8 -  // and move loads up to the first executed load.
    88.9 +  // Remove "current" from its current position in the memory graph and insert
   88.10 +  // it after the appropriate insert points (lip or uip);
   88.11 +  void remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip, Node *uip, Unique_Node_List &schd_before);
   88.12 +  // Within a store pack, schedule stores together by moving out the sandwiched memory ops according
   88.13 +  // to dependence info; and within a load pack, move loads down to the last executed load.
   88.14    void co_locate_pack(Node_List* p);
   88.15    // Convert packs into vector node operations
   88.16    void output();
    89.1 --- a/src/share/vm/prims/jvm.cpp	Wed Apr 01 22:31:26 2009 -0700
    89.2 +++ b/src/share/vm/prims/jvm.cpp	Thu Apr 02 17:01:00 2009 -0700
    89.3 @@ -1252,7 +1252,7 @@
    89.4  
    89.5             // Throws an exception if outer klass has not declared k as
    89.6             // an inner klass
    89.7 -           Reflection::check_for_inner_class(k, inner_klass, CHECK_NULL);
    89.8 +           Reflection::check_for_inner_class(k, inner_klass, true, CHECK_NULL);
    89.9  
   89.10             result->obj_at_put(members, inner_klass->java_mirror());
   89.11             members++;
   89.12 @@ -1275,16 +1275,29 @@
   89.13  
   89.14  
   89.15  JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))
   89.16 -  const int inner_class_info_index = 0;
   89.17 -  const int outer_class_info_index = 1;
   89.18 -
   89.19 +{
   89.20    // ofClass is a reference to a java_lang_Class object.
   89.21    if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
   89.22        ! Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) {
   89.23      return NULL;
   89.24    }
   89.25  
   89.26 -  instanceKlassHandle k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)));
   89.27 +  symbolOop simple_name = NULL;
   89.28 +  klassOop outer_klass
   89.29 +    = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass))
   89.30 +                          )->compute_enclosing_class(simple_name, CHECK_NULL);
   89.31 +  if (outer_klass == NULL)  return NULL;  // already a top-level class
   89.32 +  if (simple_name == NULL)  return NULL;  // an anonymous class (inside a method)
   89.33 +  return (jclass) JNIHandles::make_local(env, Klass::cast(outer_klass)->java_mirror());
   89.34 +}
   89.35 +JVM_END
   89.36 +
   89.37 +// should be in instanceKlass.cpp, but is here for historical reasons
   89.38 +klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k,
   89.39 +                                                     symbolOop& simple_name_result, TRAPS) {
   89.40 +  Thread* thread = THREAD;
   89.41 +  const int inner_class_info_index = inner_class_inner_class_info_offset;
   89.42 +  const int outer_class_info_index = inner_class_outer_class_info_offset;
   89.43  
   89.44    if (k->inner_classes()->length() == 0) {
   89.45      // No inner class info => no declaring class
   89.46 @@ -1298,35 +1311,51 @@
   89.47    bool found = false;
   89.48    klassOop ok;
   89.49    instanceKlassHandle outer_klass;
   89.50 +  bool inner_is_member = false;
   89.51 +  int simple_name_index = 0;
   89.52  
   89.53    // Find inner_klass attribute
   89.54 -  for(int i = 0; i < i_length && !found; i+= 4) {
   89.55 +  for (int i = 0; i < i_length && !found; i += inner_class_next_offset) {
   89.56      int ioff = i_icls->ushort_at(i + inner_class_info_index);
   89.57      int ooff = i_icls->ushort_at(i + outer_class_info_index);
   89.58 -
   89.59 -    if (ioff != 0 && ooff != 0) {
   89.60 +    int noff = i_icls->ushort_at(i + inner_class_inner_name_offset);
   89.61 +    if (ioff != 0) {
   89.62        // Check to see if the name matches the class we're looking for
   89.63        // before attempting to find the class.
   89.64        if (i_cp->klass_name_at_matches(k, ioff)) {
   89.65          klassOop inner_klass = i_cp->klass_at(ioff, CHECK_NULL);
   89.66 -        if (k() == inner_klass) {
   89.67 -          found = true;
   89.68 +        found = (k() == inner_klass);
   89.69 +        if (found && ooff != 0) {
   89.70            ok = i_cp->klass_at(ooff, CHECK_NULL);
   89.71            outer_klass = instanceKlassHandle(thread, ok);
   89.72 +          simple_name_index = noff;
   89.73 +          inner_is_member = true;
   89.74          }
   89.75        }
   89.76      }
   89.77    }
   89.78  
   89.79 +  if (found && outer_klass.is_null()) {
   89.80 +    // It may be anonymous; try for that.
   89.81 +    int encl_method_class_idx = k->enclosing_method_class_index();
   89.82 +    if (encl_method_class_idx != 0) {
   89.83 +      ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);
   89.84 +      outer_klass = instanceKlassHandle(thread, ok);
   89.85 +      inner_is_member = false;
   89.86 +    }
   89.87 +  }
   89.88 +
   89.89    // If no inner class attribute found for this class.
   89.90 -  if (!found) return NULL;
   89.91 +  if (outer_klass.is_null())  return NULL;
   89.92  
   89.93    // Throws an exception if outer klass has not declared k as an inner klass
   89.94 -  Reflection::check_for_inner_class(outer_klass, k, CHECK_NULL);
   89.95 -
   89.96 -  return (jclass)JNIHandles::make_local(env, outer_klass->java_mirror());
   89.97 -JVM_END
   89.98 -
   89.99 +  // We need evidence that each klass knows about the other, or else
  89.100 +  // the system could allow a spoof of an inner class to gain access rights.
  89.101 +  Reflection::check_for_inner_class(outer_klass, k, inner_is_member, CHECK_NULL);
  89.102 +
  89.103 +  simple_name_result = (inner_is_member ? i_cp->symbol_at(simple_name_index) : symbolOop(NULL));
  89.104 +  return outer_klass();
  89.105 +}
  89.106  
  89.107  JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls))
  89.108    assert (cls != NULL, "illegal class");
    90.1 --- a/src/share/vm/runtime/arguments.cpp	Wed Apr 01 22:31:26 2009 -0700
    90.2 +++ b/src/share/vm/runtime/arguments.cpp	Thu Apr 02 17:01:00 2009 -0700
    90.3 @@ -1366,9 +1366,6 @@
    90.4    if (AggressiveOpts && FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
    90.5      FLAG_SET_DEFAULT(DoEscapeAnalysis, true);
    90.6    }
    90.7 -  if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
    90.8 -    FLAG_SET_DEFAULT(SpecialArraysEquals, true);
    90.9 -  }
   90.10    if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
   90.11      FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
   90.12    }
    91.1 --- a/src/share/vm/runtime/fieldDescriptor.cpp	Wed Apr 01 22:31:26 2009 -0700
    91.2 +++ b/src/share/vm/runtime/fieldDescriptor.cpp	Thu Apr 02 17:01:00 2009 -0700
    91.3 @@ -1,5 +1,5 @@
    91.4  /*
    91.5 - * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
    91.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    91.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    91.8   *
    91.9   * This code is free software; you can redistribute it and/or modify it
   91.10 @@ -107,13 +107,14 @@
   91.11  void fieldDescriptor::print_on_for(outputStream* st, oop obj) {
   91.12    print_on(st);
   91.13    BasicType ft = field_type();
   91.14 -  jint as_int;
   91.15 +  jint as_int = 0;
   91.16    switch (ft) {
   91.17      case T_BYTE:
   91.18        as_int = (jint)obj->byte_field(offset());
   91.19        st->print(" %d", obj->byte_field(offset()));
   91.20        break;
   91.21      case T_CHAR:
   91.22 +      as_int = (jint)obj->char_field(offset());
   91.23        {
   91.24          jchar c = obj->char_field(offset());
   91.25          as_int = c;
   91.26 @@ -128,6 +129,7 @@
   91.27        st->print(" %f", obj->float_field(offset()));
   91.28        break;
   91.29      case T_INT:
   91.30 +      as_int = obj->int_field(offset());
   91.31        st->print(" %d", obj->int_field(offset()));
   91.32        break;
   91.33      case T_LONG:
   91.34 @@ -144,12 +146,12 @@
   91.35        break;
   91.36      case T_ARRAY:
   91.37        st->print(" ");
   91.38 -      as_int = obj->int_field(offset());
   91.39 +      NOT_LP64(as_int = obj->int_field(offset()));
   91.40        obj->obj_field(offset())->print_value_on(st);
   91.41        break;
   91.42      case T_OBJECT:
   91.43        st->print(" ");
   91.44 -      as_int = obj->int_field(offset());
   91.45 +      NOT_LP64(as_int = obj->int_field(offset()));
   91.46        obj->obj_field(offset())->print_value_on(st);
   91.47        break;
   91.48      default:
   91.49 @@ -158,9 +160,9 @@
   91.50    }
   91.51    // Print a hint as to the underlying integer representation. This can be wrong for
   91.52    // pointers on an LP64 machine
   91.53 -  if (ft == T_LONG || ft == T_DOUBLE) {
   91.54 +  if (ft == T_LONG || ft == T_DOUBLE LP64_ONLY(|| !is_java_primitive(ft)) ) {
   91.55      st->print(" (%x %x)", obj->int_field(offset()), obj->int_field(offset()+sizeof(jint)));
   91.56 -  } else {
   91.57 +  } else if (as_int < 0 || as_int > 9) {
   91.58      st->print(" (%x)", as_int);
   91.59    }
   91.60  }
    92.1 --- a/src/share/vm/runtime/globals.hpp	Wed Apr 01 22:31:26 2009 -0700
    92.2 +++ b/src/share/vm/runtime/globals.hpp	Thu Apr 02 17:01:00 2009 -0700
    92.3 @@ -47,6 +47,7 @@
    92.4  define_pd_global(intx, OnStackReplacePercentage,     0);
    92.5  define_pd_global(bool, ResizeTLAB,                   false);
    92.6  define_pd_global(intx, FreqInlineSize,               0);
    92.7 +define_pd_global(intx, InlineSmallCode,              0);
    92.8  define_pd_global(intx, NewSizeThreadIncrease,        4*K);
    92.9  define_pd_global(intx, NewRatio,                     4);
   92.10  define_pd_global(intx, InlineClassNatives,           true);
   92.11 @@ -490,9 +491,15 @@
   92.12    develop(bool, SpecialStringIndexOf, true,                                 \
   92.13            "special version of string indexOf")                              \
   92.14                                                                              \
   92.15 -  product(bool, SpecialArraysEquals, false,                                 \
   92.16 +  develop(bool, SpecialStringEquals, true,                                  \
   92.17 +          "special version of string equals")                               \
   92.18 +                                                                            \
   92.19 +  develop(bool, SpecialArraysEquals, true,                                  \
   92.20            "special version of Arrays.equals(char[],char[])")                \
   92.21                                                                              \
   92.22 +  product(bool, UseSSE42Intrinsics, false,                                  \
   92.23 +          "SSE4.2 versions of intrinsics")                                  \
   92.24 +                                                                            \
   92.25    develop(bool, TraceCallFixup, false,                                      \
   92.26            "traces all call fixups")                                         \
   92.27                                                                              \
   92.28 @@ -1316,6 +1323,9 @@
   92.29    product(intx, ParGCArrayScanChunk, 50,                                    \
   92.30            "Scan a subset and push remainder, if array is bigger than this") \
   92.31                                                                              \
   92.32 +  product(bool, ParGCTrimOverflow, true,                                    \
   92.33 +          "Eagerly trim the overflow lists (useful for UseCompressedOops")  \
   92.34 +                                                                            \
   92.35    notproduct(bool, ParGCWorkQueueOverflowALot, false,                       \
   92.36            "Whether we should simulate work queue overflow in ParNew")       \
   92.37                                                                              \
   92.38 @@ -2616,7 +2626,7 @@
   92.39    develop(intx, MaxRecursiveInlineLevel, 1,                                 \
   92.40            "maximum number of nested recursive calls that are inlined")      \
   92.41                                                                              \
   92.42 -  product(intx, InlineSmallCode, 1000,                                      \
   92.43 +  product_pd(intx, InlineSmallCode,                                         \
   92.44            "Only inline already compiled methods if their code size is "     \
   92.45            "less than this")                                                 \
   92.46                                                                              \
    93.1 --- a/src/share/vm/runtime/handles.hpp	Wed Apr 01 22:31:26 2009 -0700
    93.2 +++ b/src/share/vm/runtime/handles.hpp	Thu Apr 02 17:01:00 2009 -0700
    93.3 @@ -1,5 +1,5 @@
    93.4  /*
    93.5 - * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
    93.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    93.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    93.8   *
    93.9   * This code is free software; you can redistribute it and/or modify it
   93.10 @@ -137,6 +137,14 @@
   93.11      assert(is_null() || obj()->is_klass(), "not a klassOop");
   93.12    }
   93.13  
   93.14 +  // Direct interface, use very sparingly.
   93.15 +  // Used by SystemDictionaryHandles to create handles on existing WKKs.
   93.16 +  // The obj of such a klass handle may be null, because the handle is formed
   93.17 +  // during system bootstrapping.
   93.18 +  KlassHandle(klassOop *handle, bool dummy) : Handle((oop*)handle, dummy) {
   93.19 +    assert(SharedSkipVerify || is_null() || obj() == NULL || obj()->is_klass(), "not a klassOop");
   93.20 +  }
   93.21 +
   93.22    // General access
   93.23    klassOop    operator () () const               { return obj(); }
   93.24    Klass*      operator -> () const               { return as_klass(); }
    94.1 --- a/src/share/vm/runtime/orderAccess.cpp	Wed Apr 01 22:31:26 2009 -0700
    94.2 +++ b/src/share/vm/runtime/orderAccess.cpp	Thu Apr 02 17:01:00 2009 -0700
    94.3 @@ -26,3 +26,15 @@
    94.4  # include "incls/_orderAccess.cpp.incl"
    94.5  
    94.6  volatile intptr_t OrderAccess::dummy = 0;
    94.7 +
    94.8 +void OrderAccess::StubRoutines_fence() {
    94.9 +  // Use a stub if it exists.  It may not exist during bootstrap so do
   94.10 +  // nothing in that case but assert if no fence code exists after threads have been created
   94.11 +  void (*func)() = CAST_TO_FN_PTR(void (*)(), StubRoutines::fence_entry());
   94.12 +
   94.13 +  if (func != NULL) {
   94.14 +    (*func)();
   94.15 +    return;
   94.16 +  }
   94.17 +  assert(Threads::number_of_threads() == 0, "for bootstrap only");
   94.18 +}
    95.1 --- a/src/share/vm/runtime/orderAccess.hpp	Wed Apr 01 22:31:26 2009 -0700
    95.2 +++ b/src/share/vm/runtime/orderAccess.hpp	Thu Apr 02 17:01:00 2009 -0700
    95.3 @@ -300,4 +300,10 @@
    95.4    // In order to force a memory access, implementations may
    95.5    // need a volatile externally visible dummy variable.
    95.6    static volatile intptr_t dummy;
    95.7 +
    95.8 + private:
    95.9 +  // This is a helper that invokes the StubRoutines::fence_entry()
   95.10 +  // routine if it exists, It should only be used by platforms that
   95.11 +  // don't another way to do the inline eassembly.
   95.12 +  static void StubRoutines_fence();
   95.13  };
    96.1 --- a/src/share/vm/runtime/reflection.cpp	Wed Apr 01 22:31:26 2009 -0700
    96.2 +++ b/src/share/vm/runtime/reflection.cpp	Thu Apr 02 17:01:00 2009 -0700
    96.3 @@ -1,5 +1,5 @@
    96.4  /*
    96.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    96.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    96.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    96.8   *
    96.9   * This code is free software; you can redistribute it and/or modify it
   96.10 @@ -554,10 +554,18 @@
   96.11    return instanceKlass::cast(class1)->is_same_class_package(class2);
   96.12  }
   96.13  
   96.14 +bool Reflection::is_same_package_member(klassOop class1, klassOop class2, TRAPS) {
   96.15 +  return instanceKlass::cast(class1)->is_same_package_member(class2, THREAD);
   96.16 +}
   96.17 +
   96.18  
   96.19  // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
   96.20  // throw an incompatible class change exception
   96.21 -void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner, TRAPS) {
   96.22 +// If inner_is_member, require the inner to be a member of the outer.
   96.23 +// If !inner_is_member, require the inner to be anonymous (a non-member).
   96.24 +// Caller is responsible for figuring out in advance which case must be true.
   96.25 +void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
   96.26 +                                       bool inner_is_member, TRAPS) {
   96.27    const int inner_class_info_index = 0;
   96.28    const int outer_class_info_index = 1;
   96.29  
   96.30 @@ -567,7 +575,7 @@
   96.31       int ioff = icls->ushort_at(i + inner_class_info_index);
   96.32       int ooff = icls->ushort_at(i + outer_class_info_index);
   96.33  
   96.34 -     if (ioff != 0 && ooff != 0) {
   96.35 +     if (inner_is_member && ioff != 0 && ooff != 0) {
   96.36          klassOop o = cp->klass_at(ooff, CHECK);
   96.37          if (o == outer()) {
   96.38            klassOop i = cp->klass_at(ioff, CHECK);
   96.39 @@ -576,6 +584,13 @@
   96.40            }
   96.41          }
   96.42       }
   96.43 +     if (!inner_is_member && ioff != 0 && ooff == 0 &&
   96.44 +         cp->klass_name_at_matches(inner, ioff)) {
   96.45 +        klassOop i = cp->klass_at(ioff, CHECK);
   96.46 +        if (i == inner()) {
   96.47 +          return;
   96.48 +        }
   96.49 +     }
   96.50    }
   96.51  
   96.52    // 'inner' not declared as an inner klass in outer
    97.1 --- a/src/share/vm/runtime/reflection.hpp	Wed Apr 01 22:31:26 2009 -0700
    97.2 +++ b/src/share/vm/runtime/reflection.hpp	Thu Apr 02 17:01:00 2009 -0700
    97.3 @@ -1,5 +1,5 @@
    97.4  /*
    97.5 - * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
    97.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    97.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    97.8   *
    97.9   * This code is free software; you can redistribute it and/or modify it
   97.10 @@ -87,12 +87,18 @@
   97.11                                        bool classloader_only,
   97.12                                        bool protected_restriction = false);
   97.13    static bool     is_same_class_package(klassOop class1, klassOop class2);
   97.14 +  static bool     is_same_package_member(klassOop class1, klassOop class2, TRAPS);
   97.15  
   97.16    static bool can_relax_access_check_for(
   97.17      klassOop accessor, klassOop accesee, bool classloader_only);
   97.18  
   97.19    // inner class reflection
   97.20 -  static void check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner, TRAPS);
   97.21 +  // raise an ICCE unless the required relationship can be proven to hold
   97.22 +  // If inner_is_member, require the inner to be a member of the outer.
   97.23 +  // If !inner_is_member, require the inner to be anonymous (a non-member).
   97.24 +  // Caller is responsible for figuring out in advance which case must be true.
   97.25 +  static void check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
   97.26 +                                    bool inner_is_member, TRAPS);
   97.27  
   97.28    //
   97.29    // Support for reflection based on dynamic bytecode generation (JDK 1.4)
    98.1 --- a/src/share/vm/runtime/sharedRuntime.cpp	Wed Apr 01 22:31:26 2009 -0700
    98.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp	Thu Apr 02 17:01:00 2009 -0700
    98.3 @@ -675,48 +675,6 @@
    98.4  JRT_END
    98.5  
    98.6  
    98.7 -// ---------------------------------------------------------------------------------------------------------
    98.8 -// Non-product code
    98.9 -#ifndef PRODUCT
   98.10 -
   98.11 -void SharedRuntime::verify_caller_frame(frame caller_frame, methodHandle callee_method) {
   98.12 -  ResourceMark rm;
   98.13 -  assert (caller_frame.is_interpreted_frame(), "sanity check");
   98.14 -  assert (callee_method->has_compiled_code(), "callee must be compiled");
   98.15 -  methodHandle caller_method (Thread::current(), caller_frame.interpreter_frame_method());
   98.16 -  jint bci = caller_frame.interpreter_frame_bci();
   98.17 -  methodHandle method = find_callee_method_inside_interpreter(caller_frame, caller_method, bci);
   98.18 -  assert (callee_method == method, "incorrect method");
   98.19 -}
   98.20 -
   98.21 -methodHandle SharedRuntime::find_callee_method_inside_interpreter(frame caller_frame, methodHandle caller_method, int bci) {
   98.22 -  EXCEPTION_MARK;
   98.23 -  Bytecode_invoke* bytecode = Bytecode_invoke_at(caller_method, bci);
   98.24 -  methodHandle staticCallee = bytecode->static_target(CATCH); // Non-product code
   98.25 -
   98.26 -  bytecode = Bytecode_invoke_at(caller_method, bci);
   98.27 -  int bytecode_index = bytecode->index();
   98.28 -  Bytecodes::Code bc = bytecode->adjusted_invoke_code();
   98.29 -
   98.30 -  Handle receiver;
   98.31 -  if (bc == Bytecodes::_invokeinterface ||
   98.32 -      bc == Bytecodes::_invokevirtual ||
   98.33 -      bc == Bytecodes::_invokespecial) {
   98.34 -    symbolHandle signature (THREAD, staticCallee->signature());
   98.35 -    receiver = Handle(THREAD, retrieve_receiver(signature, caller_frame));
   98.36 -  } else {
   98.37 -    receiver = Handle();
   98.38 -  }
   98.39 -  CallInfo result;
   98.40 -  constantPoolHandle constants (THREAD, caller_method->constants());
   98.41 -  LinkResolver::resolve_invoke(result, receiver, constants, bytecode_index, bc, CATCH); // Non-product code
   98.42 -  methodHandle calleeMethod = result.selected_method();
   98.43 -  return calleeMethod;
   98.44 -}
   98.45 -
   98.46 -#endif  // PRODUCT
   98.47 -
   98.48 -
   98.49  JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
   98.50    assert(obj->is_oop(), "must be a valid oop");
   98.51    assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise");
    99.1 --- a/src/share/vm/runtime/sharedRuntime.hpp	Wed Apr 01 22:31:26 2009 -0700
    99.2 +++ b/src/share/vm/runtime/sharedRuntime.hpp	Thu Apr 02 17:01:00 2009 -0700
    99.3 @@ -1,5 +1,5 @@
    99.4  /*
    99.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
    99.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    99.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    99.8   *
    99.9   * This code is free software; you can redistribute it and/or modify it
   99.10 @@ -180,9 +180,6 @@
   99.11  
   99.12    static oop retrieve_receiver( symbolHandle sig, frame caller );
   99.13  
   99.14 -  static void verify_caller_frame(frame caller_frame, methodHandle callee_method) PRODUCT_RETURN;
   99.15 -  static methodHandle find_callee_method_inside_interpreter(frame caller_frame, methodHandle caller_method, int bci) PRODUCT_RETURN_(return methodHandle(););
   99.16 -
   99.17    static void register_finalizer(JavaThread* thread, oopDesc* obj);
   99.18  
   99.19    // dtrace notifications
   100.1 --- a/src/share/vm/runtime/thread.cpp	Wed Apr 01 22:31:26 2009 -0700
   100.2 +++ b/src/share/vm/runtime/thread.cpp	Thu Apr 02 17:01:00 2009 -0700
   100.3 @@ -3007,17 +3007,19 @@
   100.4        }
   100.5  
   100.6        if (UseStringCache) {
   100.7 -        // Forcibly initialize java/lang/String and mutate the private
   100.8 +        // Forcibly initialize java/lang/StringValue and mutate the private
   100.9          // static final "stringCacheEnabled" field before we start creating instances
  100.10 -        klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_String(), Handle(), Handle(), CHECK_0);
  100.11 -        KlassHandle k = KlassHandle(THREAD, k_o);
  100.12 -        guarantee(k.not_null(), "Must find java/lang/String");
  100.13 -        instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
  100.14 -        ik->initialize(CHECK_0);
  100.15 -        fieldDescriptor fd;
  100.16 -        // Possible we might not find this field; if so, don't break
  100.17 -        if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
  100.18 -          k()->bool_field_put(fd.offset(), true);
  100.19 +        klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_StringValue(), Handle(), Handle(), CHECK_0);
  100.20 +        // Possible that StringValue isn't present: if so, silently don't break
  100.21 +        if (k_o != NULL) {
  100.22 +          KlassHandle k = KlassHandle(THREAD, k_o);
  100.23 +          instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
  100.24 +          ik->initialize(CHECK_0);
  100.25 +          fieldDescriptor fd;
  100.26 +          // Possible we might not find this field: if so, silently don't break
  100.27 +          if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
  100.28 +            k()->bool_field_put(fd.offset(), true);
  100.29 +          }
  100.30          }
  100.31        }
  100.32      }
   101.1 --- a/src/share/vm/runtime/vm_operations.hpp	Wed Apr 01 22:31:26 2009 -0700
   101.2 +++ b/src/share/vm/runtime/vm_operations.hpp	Thu Apr 02 17:01:00 2009 -0700
   101.3 @@ -59,7 +59,6 @@
   101.4    template(G1CollectFull)                         \
   101.5    template(G1CollectForAllocation)                \
   101.6    template(G1IncCollectionPause)                  \
   101.7 -  template(G1PopRegionCollectionPause)            \
   101.8    template(EnableBiasedLocking)                   \
   101.9    template(RevokeBias)                            \
  101.10    template(BulkRevokeBias)                        \
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/test/compiler/6636138/Test1.java	Thu Apr 02 17:01:00 2009 -0700
   102.3 @@ -0,0 +1,67 @@
   102.4 +/*
   102.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   102.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   102.7 + *
   102.8 + * This code is free software; you can redistribute it and/or modify it
   102.9 + * under the terms of the GNU General Public License version 2 only, as
  102.10 + * published by the Free Software Foundation.
  102.11 + *
  102.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  102.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  102.15 + * version 2 for more details (a copy is included in the LICENSE file that
  102.16 + * accompanied this code).
  102.17 + *
  102.18 + * You should have received a copy of the GNU General Public License version
  102.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  102.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  102.21 + *
  102.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  102.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  102.24 + * have any questions.
  102.25 + */
  102.26 +
  102.27 +/**
  102.28 + * @test
  102.29 + * @bug 6636138
  102.30 + * @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation.
  102.31 + *
  102.32 + * @run main/othervm -server -Xbatch -XX:CompileOnly=Test1.init -XX:+UseSuperword Test1
  102.33 + */
  102.34 +
  102.35 +class Test1 {
  102.36 +
  102.37 +    public static void init(int src[], int [] dst, int[] ref) {
  102.38 +        // initialize the arrays
  102.39 +        for (int i =0; i<src.length; i++) {
  102.40 +            src[i] =  i;
  102.41 +            dst[i] = 2;      // yes, dst[i] needed(otherwise src[i] will be replaced with i)
  102.42 +            ref[i] = src[i]; // src[i] depends on the store src[i]
  102.43 +        }
  102.44 +    }
  102.45 +
  102.46 +    public static void verify(int src[], int[] ref) {
  102.47 +        // check whether src and ref are equal
  102.48 +        for (int i = 0; i < src.length; i++) {
  102.49 +            if (src[i] != ref[i]) {
  102.50 +                System.out.println("Error: src and ref don't match at " + i);
  102.51 +                System.exit(-1);
  102.52 +            }
  102.53 +        }
  102.54 +    }
  102.55 +
  102.56 +    public static void test() {
  102.57 +        int[] src = new int[34];
  102.58 +        int[] dst = new int[34];
  102.59 +        int[] ref = new int[34];
  102.60 +
  102.61 +        init(src, dst, ref);
  102.62 +        verify(src, ref);
  102.63 +    }
  102.64 +
  102.65 +    public static void main(String[] args) {
  102.66 +        for (int i=0; i< 2000; i++) {
  102.67 +            test();
  102.68 +        }
  102.69 +    }
  102.70 +}
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/test/compiler/6636138/Test2.java	Thu Apr 02 17:01:00 2009 -0700
   103.3 @@ -0,0 +1,70 @@
   103.4 +/*
   103.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   103.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   103.7 + *
   103.8 + * This code is free software; you can redistribute it and/or modify it
   103.9 + * under the terms of the GNU General Public License version 2 only, as
  103.10 + * published by the Free Software Foundation.
  103.11 + *
  103.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  103.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  103.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  103.15 + * version 2 for more details (a copy is included in the LICENSE file that
  103.16 + * accompanied this code).
  103.17 + *
  103.18 + * You should have received a copy of the GNU General Public License version
  103.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  103.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  103.21 + *
  103.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  103.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  103.24 + * have any questions.
  103.25 + */
  103.26 +
  103.27 +/**
  103.28 + * @test
  103.29 + * @bug 6636138
  103.30 + * @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation.
  103.31 + *
  103.32 + * @run main/othervm -server -Xbatch -XX:CompileOnly=Test2.shift -XX:+UseSuperword Test2
  103.33 + */
  103.34 +
  103.35 +class Test2 {
  103.36 +
  103.37 +    public static void init(int src[]) {
  103.38 +        // Initialize the array
  103.39 +        for (int i = 0; i < src.length; i++)
  103.40 +            src[i] = i;
  103.41 +    }
  103.42 +
  103.43 +   public static void shift(int src[]) {
  103.44 +       //left-shift the array
  103.45 +       for (int i = src.length-1; i > 0; i--){
  103.46 +           int tmp  = src[i];
  103.47 +           src[i]   = src[i-1];
  103.48 +           src[i-1] = tmp;
  103.49 +       }
  103.50 +    }
  103.51 +
  103.52 +    public static void verify(int src[]) {
  103.53 +        for (int i = 0; i < src.length; i++){
  103.54 +            int value = (i-1 + src.length)%src.length; // correct value after shifting
  103.55 +                if (src[i] != value) {
  103.56 +                    System.out.println("Error: src["+i+"] should be "+ value + " instead of " + src[i]);
  103.57 +                    System.exit(-1);
  103.58 +                }
  103.59 +        }
  103.60 +    }
  103.61 +
  103.62 +    public static void test() {
  103.63 +        int[] src = new int[10];
  103.64 +        init(src);
  103.65 +        shift(src);
  103.66 +        verify(src);
  103.67 +    }
  103.68 +
  103.69 +    public static void main(String[] args) {
  103.70 +        for (int i=0; i< 2000; i++)
  103.71 +            test();
  103.72 +    }
  103.73 +}

mercurial