Merge

Mon, 23 Jan 2012 17:45:32 -0800

author
coleenp
date
Mon, 23 Jan 2012 17:45:32 -0800
changeset 3469
583b428aa858
parent 3468
af739d5ab23c
parent 3432
db18ca98d237
child 3470
d6660fedbab5
child 3471
bf864f701a4a

Merge

src/os/bsd/vm/decoder_bsd.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Sat Jan 21 23:02:40 2012 -0500
     1.2 +++ b/.hgtags	Mon Jan 23 17:45:32 2012 -0800
     1.3 @@ -207,3 +207,7 @@
     1.4  a2fef924d8e6f37dac2a887315e3502876cc8e24 hs23-b08
     1.5  61165f53f1656b9f99e4fb806429bf98b99d59c3 jdk8-b18
     1.6  4bcf61041217f8677dcec18e90e9196acc945bba hs23-b09
     1.7 +9232e0ecbc2cec54dcc8f93004fb00c214446460 jdk8-b19
     1.8 +fe2c8764998112b7fefcd7d41599714813ae4327 jdk8-b20
     1.9 +9952d1c439d64c5fd4ad1236a63a62bd5a49d4c3 jdk8-b21
    1.10 +513351373923f74a7c91755748b95c9771e59f96 hs23-b10
     2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Sat Jan 21 23:02:40 2012 -0500
     2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Mon Jan 23 17:45:32 2012 -0800
     2.3 @@ -63,8 +63,6 @@
     2.4    private static int CLASS_STATE_FULLY_INITIALIZED;
     2.5    private static int CLASS_STATE_INITIALIZATION_ERROR;
     2.6  
     2.7 -  private static int IS_MARKED_DEPENDENT_MASK;
     2.8 -
     2.9    private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
    2.10      Type type            = db.lookupType("instanceKlass");
    2.11      arrayKlasses         = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize());
    2.12 @@ -92,7 +90,7 @@
    2.13      staticFieldSize      = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
    2.14      staticOopFieldCount   = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
    2.15      nonstaticOopMapSize  = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
    2.16 -    miscFlags            = new CIntField(type.getCIntegerField("_misc_flags"), Oop.getHeaderSize());
    2.17 +    isMarkedDependent    = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize());
    2.18      initState            = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
    2.19      vtableLen            = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize());
    2.20      itableLen            = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize());
    2.21 @@ -120,8 +118,6 @@
    2.22      CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue();
    2.23      CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue();
    2.24  
    2.25 -    IS_MARKED_DEPENDENT_MASK = db.lookupIntConstant("instanceKlass::IS_MARKED_DEPENDENT").intValue();
    2.26 -
    2.27    }
    2.28  
    2.29    InstanceKlass(OopHandle handle, ObjectHeap heap) {
    2.30 @@ -155,7 +151,7 @@
    2.31    private static CIntField staticFieldSize;
    2.32    private static CIntField staticOopFieldCount;
    2.33    private static CIntField nonstaticOopMapSize;
    2.34 -  private static CIntField miscFlags;
    2.35 +  private static CIntField isMarkedDependent;
    2.36    private static CIntField initState;
    2.37    private static CIntField vtableLen;
    2.38    private static CIntField itableLen;
    2.39 @@ -337,7 +333,7 @@
    2.40    public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
    2.41    public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
    2.42    public long      getNonstaticOopMapSize() { return                nonstaticOopMapSize.getValue(this); }
    2.43 -  public boolean   getIsMarkedDependent()   { return                (miscFlags.getValue(this) & IS_MARKED_DEPENDENT_MASK) != 0; }
    2.44 +  public boolean   getIsMarkedDependent()   { return                isMarkedDependent.getValue(this) != 0; }
    2.45    public long      getVtableLen()           { return                vtableLen.getValue(this); }
    2.46    public long      getItableLen()           { return                itableLen.getValue(this); }
    2.47    public Symbol    getGenericSignature()    { return getSymbol(genericSignature); }
    2.48 @@ -528,7 +524,7 @@
    2.49        visitor.doCInt(staticFieldSize, true);
    2.50        visitor.doCInt(staticOopFieldCount, true);
    2.51        visitor.doCInt(nonstaticOopMapSize, true);
    2.52 -      visitor.doCInt(miscFlags, true);
    2.53 +      visitor.doCInt(isMarkedDependent, true);
    2.54        visitor.doCInt(initState, true);
    2.55        visitor.doCInt(vtableLen, true);
    2.56        visitor.doCInt(itableLen, true);
     3.1 --- a/make/hotspot_version	Sat Jan 21 23:02:40 2012 -0500
     3.2 +++ b/make/hotspot_version	Mon Jan 23 17:45:32 2012 -0800
     3.3 @@ -35,7 +35,7 @@
     3.4  
     3.5  HS_MAJOR_VER=23
     3.6  HS_MINOR_VER=0
     3.7 -HS_BUILD_NUMBER=10
     3.8 +HS_BUILD_NUMBER=11
     3.9  
    3.10  JDK_MAJOR_VER=1
    3.11  JDK_MINOR_VER=8
     4.1 --- a/src/cpu/sparc/vm/sparc.ad	Sat Jan 21 23:02:40 2012 -0500
     4.2 +++ b/src/cpu/sparc/vm/sparc.ad	Mon Jan 23 17:45:32 2012 -0800
     4.3 @@ -9283,6 +9283,7 @@
     4.4  // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
     4.5  instruct jumpXtnd(iRegX switch_val, o7RegI table) %{
     4.6    match(Jump switch_val);
     4.7 +  effect(TEMP table);
     4.8  
     4.9    ins_cost(350);
    4.10  
    4.11 @@ -10273,24 +10274,24 @@
    4.12  // ============================================================================
    4.13  // inlined locking and unlocking
    4.14  
    4.15 -instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{
    4.16 +instruct cmpFastLock(flagsRegP pcc, iRegP object, o1RegP box, iRegP scratch2, o7RegP scratch ) %{
    4.17    match(Set pcc (FastLock object box));
    4.18  
    4.19 -  effect(KILL scratch, TEMP scratch2);
    4.20 +  effect(TEMP scratch2, USE_KILL box, KILL scratch);
    4.21    ins_cost(100);
    4.22  
    4.23 -  format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $box" %}
    4.24 +  format %{ "FASTLOCK  $object,$box\t! kills $box,$scratch,$scratch2" %}
    4.25    ins_encode( Fast_Lock(object, box, scratch, scratch2) );
    4.26    ins_pipe(long_memory_op);
    4.27  %}
    4.28  
    4.29  
    4.30 -instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{
    4.31 +instruct cmpFastUnlock(flagsRegP pcc, iRegP object, o1RegP box, iRegP scratch2, o7RegP scratch ) %{
    4.32    match(Set pcc (FastUnlock object box));
    4.33 -  effect(KILL scratch, TEMP scratch2);
    4.34 +  effect(TEMP scratch2, USE_KILL box, KILL scratch);
    4.35    ins_cost(100);
    4.36  
    4.37 -  format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $box" %}
    4.38 +  format %{ "FASTUNLOCK  $object,$box\t! kills $box,$scratch,$scratch2" %}
    4.39    ins_encode( Fast_Unlock(object, box, scratch, scratch2) );
    4.40    ins_pipe(long_memory_op);
    4.41  %}
     5.1 --- a/src/cpu/x86/vm/x86_32.ad	Sat Jan 21 23:02:40 2012 -0500
     5.2 +++ b/src/cpu/x86/vm/x86_32.ad	Mon Jan 23 17:45:32 2012 -0800
     5.3 @@ -13435,20 +13435,20 @@
     5.4  // inlined locking and unlocking
     5.5  
     5.6  
     5.7 -instruct cmpFastLock( eFlagsReg cr, eRegP object, eRegP box, eAXRegI tmp, eRegP scr) %{
     5.8 +instruct cmpFastLock( eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP scr) %{
     5.9    match( Set cr (FastLock object box) );
    5.10 -  effect( TEMP tmp, TEMP scr );
    5.11 +  effect( TEMP tmp, TEMP scr, USE_KILL box );
    5.12    ins_cost(300);
    5.13 -  format %{ "FASTLOCK $object, $box KILLS $tmp,$scr" %}
    5.14 +  format %{ "FASTLOCK $object,$box\t! kills $box,$tmp,$scr" %}
    5.15    ins_encode( Fast_Lock(object,box,tmp,scr) );
    5.16    ins_pipe( pipe_slow );
    5.17  %}
    5.18  
    5.19  instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
    5.20    match( Set cr (FastUnlock object box) );
    5.21 -  effect( TEMP tmp );
    5.22 +  effect( TEMP tmp, USE_KILL box );
    5.23    ins_cost(300);
    5.24 -  format %{ "FASTUNLOCK $object, $box, $tmp" %}
    5.25 +  format %{ "FASTUNLOCK $object,$box\t! kills $box,$tmp" %}
    5.26    ins_encode( Fast_Unlock(object,box,tmp) );
    5.27    ins_pipe( pipe_slow );
    5.28  %}
     6.1 --- a/src/cpu/x86/vm/x86_64.ad	Sat Jan 21 23:02:40 2012 -0500
     6.2 +++ b/src/cpu/x86/vm/x86_64.ad	Mon Jan 23 17:45:32 2012 -0800
     6.3 @@ -11511,13 +11511,13 @@
     6.4  // inlined locking and unlocking
     6.5  
     6.6  instruct cmpFastLock(rFlagsReg cr,
     6.7 -                     rRegP object, rRegP box, rax_RegI tmp, rRegP scr)
     6.8 +                     rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
     6.9  %{
    6.10    match(Set cr (FastLock object box));
    6.11 -  effect(TEMP tmp, TEMP scr);
    6.12 +  effect(TEMP tmp, TEMP scr, USE_KILL box);
    6.13  
    6.14    ins_cost(300);
    6.15 -  format %{ "fastlock $object,$box,$tmp,$scr" %}
    6.16 +  format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
    6.17    ins_encode(Fast_Lock(object, box, tmp, scr));
    6.18    ins_pipe(pipe_slow);
    6.19  %}
    6.20 @@ -11526,10 +11526,10 @@
    6.21                         rRegP object, rax_RegP box, rRegP tmp)
    6.22  %{
    6.23    match(Set cr (FastUnlock object box));
    6.24 -  effect(TEMP tmp);
    6.25 +  effect(TEMP tmp, USE_KILL box);
    6.26  
    6.27    ins_cost(300);
    6.28 -  format %{ "fastunlock $object, $box, $tmp" %}
    6.29 +  format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
    6.30    ins_encode(Fast_Unlock(object, box, tmp));
    6.31    ins_pipe(pipe_slow);
    6.32  %}
     7.1 --- a/src/os/bsd/vm/decoder_bsd.cpp	Sat Jan 21 23:02:40 2012 -0500
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,66 +0,0 @@
     7.4 -/*
     7.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 - *
     7.8 - * This code is free software; you can redistribute it and/or modify it
     7.9 - * under the terms of the GNU General Public License version 2 only, as
    7.10 - * published by the Free Software Foundation.
    7.11 - *
    7.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 - * version 2 for more details (a copy is included in the LICENSE file that
    7.16 - * accompanied this code).
    7.17 - *
    7.18 - * You should have received a copy of the GNU General Public License version
    7.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 - *
    7.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 - * or visit www.oracle.com if you need additional information or have any
    7.24 - * questions.
    7.25 - *
    7.26 - */
    7.27 -
    7.28 -#include "prims/jvm.h"
    7.29 -#include "utilities/decoder.hpp"
    7.30 -
    7.31 -#include <cxxabi.h>
    7.32 -
    7.33 -#ifdef __APPLE__
    7.34 -
    7.35 -void Decoder::initialize() {
    7.36 -  _initialized = true;
    7.37 -}
    7.38 -
    7.39 -void Decoder::uninitialize() {
    7.40 -  _initialized = false;
    7.41 -}
    7.42 -
    7.43 -bool Decoder::can_decode_C_frame_in_vm() {
    7.44 -  return false;
    7.45 -}
    7.46 -
    7.47 -Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
    7.48 -  return symbol_not_found;
    7.49 -}
    7.50 -
    7.51 -
    7.52 -#endif
    7.53 -
    7.54 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
    7.55 -  int   status;
    7.56 -  char* result;
    7.57 -  size_t size = (size_t)buflen;
    7.58 -
    7.59 -  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
    7.60 -  // __cxa_demangle will call system "realloc" for additional memory, which
    7.61 -  // may use different malloc/realloc mechanism that allocates 'buf'.
    7.62 -  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
    7.63 -    jio_snprintf(buf, buflen, "%s", result);
    7.64 -      // call c library's free
    7.65 -      ::free(result);
    7.66 -      return true;
    7.67 -  }
    7.68 -  return false;
    7.69 -}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/os/bsd/vm/decoder_machO.cpp	Mon Jan 23 17:45:32 2012 -0800
     8.3 @@ -0,0 +1,31 @@
     8.4 +/*
     8.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + *
    8.26 + */
    8.27 +
    8.28 +#include "precompiled.hpp"
    8.29 +
    8.30 +#ifdef __APPLE__
    8.31 +#include "decoder_machO.hpp"
    8.32 +#endif
    8.33 +
    8.34 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/os/bsd/vm/decoder_machO.hpp	Mon Jan 23 17:45:32 2012 -0800
     9.3 @@ -0,0 +1,42 @@
     9.4 +/*
     9.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + *
    9.26 + */
    9.27 +
    9.28 +#ifndef OS_BSD_VM_DECODER_MACHO_HPP
    9.29 +#define OS_BSD_VM_DECODER_MACHO_HPP
    9.30 +
    9.31 +#ifdef __APPLE__
    9.32 +
    9.33 +#include "utilities/decoder.hpp"
    9.34 +
    9.35 +// Just a placehold for now
    9.36 +class MachODecoder: public NullDecoder {
    9.37 +public:
    9.38 +  MachODecoder() { }
    9.39 +  ~MachODecoder() { }
    9.40 +};
    9.41 +
    9.42 +#endif
    9.43 +
    9.44 +#endif // OS_BSD_VM_DECODER_MACHO_HPP
    9.45 +
    10.1 --- a/src/os/bsd/vm/os_bsd.cpp	Sat Jan 21 23:02:40 2012 -0500
    10.2 +++ b/src/os/bsd/vm/os_bsd.cpp	Mon Jan 23 17:45:32 2012 -0800
    10.3 @@ -1920,7 +1920,7 @@
    10.4      return true;
    10.5    } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    10.6      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    10.7 -       dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
    10.8 +       buf, buflen, offset, dlinfo.dli_fname)) {
    10.9         return true;
   10.10      }
   10.11    }
    11.1 --- a/src/os/linux/vm/decoder_linux.cpp	Sat Jan 21 23:02:40 2012 -0500
    11.2 +++ b/src/os/linux/vm/decoder_linux.cpp	Mon Jan 23 17:45:32 2012 -0800
    11.3 @@ -23,11 +23,11 @@
    11.4   */
    11.5  
    11.6  #include "prims/jvm.h"
    11.7 -#include "utilities/decoder.hpp"
    11.8 +#include "utilities/decoder_elf.hpp"
    11.9  
   11.10  #include <cxxabi.h>
   11.11  
   11.12 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
   11.13 +bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
   11.14    int   status;
   11.15    char* result;
   11.16    size_t size = (size_t)buflen;
   11.17 @@ -43,3 +43,4 @@
   11.18    }
   11.19    return false;
   11.20  }
   11.21 +
    12.1 --- a/src/os/linux/vm/os_linux.cpp	Sat Jan 21 23:02:40 2012 -0500
    12.2 +++ b/src/os/linux/vm/os_linux.cpp	Mon Jan 23 17:45:32 2012 -0800
    12.3 @@ -1732,7 +1732,7 @@
    12.4      return true;
    12.5    } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    12.6      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    12.7 -       dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
    12.8 +        buf, buflen, offset, dlinfo.dli_fname)) {
    12.9         return true;
   12.10      }
   12.11    }
    13.1 --- a/src/os/solaris/vm/decoder_solaris.cpp	Sat Jan 21 23:02:40 2012 -0500
    13.2 +++ b/src/os/solaris/vm/decoder_solaris.cpp	Mon Jan 23 17:45:32 2012 -0800
    13.3 @@ -22,10 +22,11 @@
    13.4   *
    13.5   */
    13.6  
    13.7 -#include "utilities/decoder.hpp"
    13.8 +#include "utilities/decoder_elf.hpp"
    13.9  
   13.10  #include <demangle.h>
   13.11  
   13.12 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
   13.13 +bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
   13.14    return !cplus_demangle(symbol, buf, (size_t)buflen);
   13.15  }
   13.16 +
    14.1 --- a/src/os/solaris/vm/os_solaris.cpp	Sat Jan 21 23:02:40 2012 -0500
    14.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Mon Jan 23 17:45:32 2012 -0800
    14.3 @@ -1997,7 +1997,7 @@
    14.4        }
    14.5        if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    14.6          if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    14.7 -          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
    14.8 +           buf, buflen, offset, dlinfo.dli_fname)) {
    14.9            return true;
   14.10          }
   14.11        }
   14.12 @@ -2015,7 +2015,7 @@
   14.13          return true;
   14.14        } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
   14.15          if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
   14.16 -          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
   14.17 +          buf, buflen, offset, dlinfo.dli_fname)) {
   14.18            return true;
   14.19          }
   14.20        }
    15.1 --- a/src/os/windows/vm/decoder_windows.cpp	Sat Jan 21 23:02:40 2012 -0500
    15.2 +++ b/src/os/windows/vm/decoder_windows.cpp	Mon Jan 23 17:45:32 2012 -0800
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    15.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    15.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.8   *
    15.9   * This code is free software; you can redistribute it and/or modify it
   15.10 @@ -24,22 +24,24 @@
   15.11  
   15.12  #include "precompiled.hpp"
   15.13  #include "prims/jvm.h"
   15.14 -#include "runtime/os.hpp"
   15.15 -#include "utilities/decoder.hpp"
   15.16 +#include "decoder_windows.hpp"
   15.17  
   15.18 -HMODULE                   Decoder::_dbghelp_handle = NULL;
   15.19 -bool                      Decoder::_can_decode_in_vm = false;
   15.20 -pfn_SymGetSymFromAddr64   Decoder::_pfnSymGetSymFromAddr64 = NULL;
   15.21 -pfn_UndecorateSymbolName  Decoder::_pfnUndecorateSymbolName = NULL;
   15.22 +WindowsDecoder::WindowsDecoder() {
   15.23 +  _dbghelp_handle = NULL;
   15.24 +  _can_decode_in_vm = false;
   15.25 +  _pfnSymGetSymFromAddr64 = NULL;
   15.26 +  _pfnUndecorateSymbolName = NULL;
   15.27  
   15.28 -void Decoder::initialize() {
   15.29 -  if (!_initialized) {
   15.30 -    _initialized = true;
   15.31 +  _decoder_status = no_error;
   15.32 +  initialize();
   15.33 +}
   15.34  
   15.35 -    HINSTANCE handle = os::win32::load_Windows_dll("dbghelp.dll", NULL, 0);
   15.36 +void WindowsDecoder::initialize() {
   15.37 +  if (!has_error() && _dbghelp_handle == NULL) {
   15.38 +    HMODULE handle = ::LoadLibrary("dbghelp.dll");
   15.39      if (!handle) {
   15.40        _decoder_status = helper_not_found;
   15.41 -        return;
   15.42 +      return;
   15.43      }
   15.44  
   15.45      _dbghelp_handle = handle;
   15.46 @@ -70,32 +72,29 @@
   15.47  
   15.48       // find out if jvm.dll contains private symbols, by decoding
   15.49       // current function and comparing the result
   15.50 -     address addr = (address)Decoder::initialize;
   15.51 +     address addr = (address)Decoder::decode;
   15.52       char buf[MAX_PATH];
   15.53 -     if (decode(addr, buf, sizeof(buf), NULL) == no_error) {
   15.54 -       _can_decode_in_vm = !strcmp(buf, "Decoder::initialize");
   15.55 +     if (decode(addr, buf, sizeof(buf), NULL)) {
   15.56 +       _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
   15.57       }
   15.58    }
   15.59  }
   15.60  
   15.61 -void Decoder::uninitialize() {
   15.62 -  assert(_initialized, "Decoder not yet initialized");
   15.63 +void WindowsDecoder::uninitialize() {
   15.64    _pfnSymGetSymFromAddr64 = NULL;
   15.65    _pfnUndecorateSymbolName = NULL;
   15.66    if (_dbghelp_handle != NULL) {
   15.67      ::FreeLibrary(_dbghelp_handle);
   15.68    }
   15.69 -  _initialized = false;
   15.70 +  _dbghelp_handle = NULL;
   15.71  }
   15.72  
   15.73 -bool Decoder::can_decode_C_frame_in_vm() {
   15.74 -  initialize();
   15.75 -  return  _can_decode_in_vm;
   15.76 +bool WindowsDecoder::can_decode_C_frame_in_vm() const {
   15.77 +  return  (!has_error() && _can_decode_in_vm);
   15.78  }
   15.79  
   15.80  
   15.81 -Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) {
   15.82 -  assert(_initialized, "Decoder not yet initialized");
   15.83 +bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath)  {
   15.84    if (_pfnSymGetSymFromAddr64 != NULL) {
   15.85      PIMAGEHLP_SYMBOL64 pSymbol;
   15.86      char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
   15.87 @@ -105,19 +104,20 @@
   15.88      DWORD64 displacement;
   15.89      if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
   15.90        if (buf != NULL) {
   15.91 -        if (!demangle(pSymbol->Name, buf, buflen)) {
   15.92 +        if (demangle(pSymbol->Name, buf, buflen)) {
   15.93            jio_snprintf(buf, buflen, "%s", pSymbol->Name);
   15.94          }
   15.95        }
   15.96 -      if (offset != NULL) *offset = (int)displacement;
   15.97 -      return no_error;
   15.98 +      if(offset != NULL) *offset = (int)displacement;
   15.99 +      return true;
  15.100      }
  15.101    }
  15.102 -  return helper_not_found;
  15.103 +  if (buf != NULL && buflen > 0) buf[0] = '\0';
  15.104 +  if (offset != NULL) *offset = -1;
  15.105 +  return false;
  15.106  }
  15.107  
  15.108 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
  15.109 -  assert(_initialized, "Decoder not yet initialized");
  15.110 +bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
  15.111    return _pfnUndecorateSymbolName != NULL &&
  15.112           _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
  15.113  }
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/os/windows/vm/decoder_windows.hpp	Mon Jan 23 17:45:32 2012 -0800
    16.3 @@ -0,0 +1,61 @@
    16.4 +/*
    16.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + *
   16.26 + */
   16.27 +
   16.28 +#ifndef OS_WINDOWS_VM_DECODER_WINDOWS_HPP
   16.29 +#define OS_WINDOWS_VM_DECIDER_WINDOWS_HPP
   16.30 +
   16.31 +#include <windows.h>
   16.32 +#include <imagehlp.h>
   16.33 +
   16.34 +#include "utilities/decoder.hpp"
   16.35 +
   16.36 +// functions needed for decoding symbols
   16.37 +typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
   16.38 +typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
   16.39 +typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
   16.40 +typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
   16.41 +
   16.42 +class WindowsDecoder: public NullDecoder {
   16.43 +
   16.44 +public:
   16.45 +  WindowsDecoder();
   16.46 +  ~WindowsDecoder() { uninitialize(); };
   16.47 +
   16.48 +  bool can_decode_C_frame_in_vm() const;
   16.49 +  bool demangle(const char* symbol, char *buf, int buflen);
   16.50 +  bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
   16.51 +
   16.52 +private:
   16.53 +  void initialize();
   16.54 +  void uninitialize();
   16.55 +
   16.56 +private:
   16.57 +  HMODULE                   _dbghelp_handle;
   16.58 +  bool                      _can_decode_in_vm;
   16.59 +  pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
   16.60 +  pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
   16.61 +};
   16.62 +
   16.63 +#endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP
   16.64 +
    17.1 --- a/src/os/windows/vm/os_windows.cpp	Sat Jan 21 23:02:40 2012 -0500
    17.2 +++ b/src/os/windows/vm/os_windows.cpp	Mon Jan 23 17:45:32 2012 -0800
    17.3 @@ -1391,7 +1391,7 @@
    17.4  
    17.5  bool os::dll_address_to_function_name(address addr, char *buf,
    17.6                                        int buflen, int *offset) {
    17.7 -  if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
    17.8 +  if (Decoder::decode(addr, buf, buflen, offset)) {
    17.9      return true;
   17.10    }
   17.11    if (offset != NULL)  *offset  = -1;
    18.1 --- a/src/share/vm/ci/ciTypeFlow.cpp	Sat Jan 21 23:02:40 2012 -0500
    18.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp	Mon Jan 23 17:45:32 2012 -0800
    18.3 @@ -1589,7 +1589,7 @@
    18.4    _next = NULL;
    18.5    _on_work_list = false;
    18.6    _backedge_copy = false;
    18.7 -  _exception_entry = false;
    18.8 +  _has_monitorenter = false;
    18.9    _trap_bci = -1;
   18.10    _trap_index = 0;
   18.11    df_init();
   18.12 @@ -2182,6 +2182,10 @@
   18.13          !head->is_clonable_exit(lp))
   18.14        continue;
   18.15  
   18.16 +    // Avoid BoxLock merge.
   18.17 +    if (EliminateNestedLocks && head->has_monitorenter())
   18.18 +      continue;
   18.19 +
   18.20      // check not already cloned
   18.21      if (head->backedge_copy_count() != 0)
   18.22        continue;
   18.23 @@ -2322,6 +2326,10 @@
   18.24      // Watch for bailouts.
   18.25      if (failing())  return;
   18.26  
   18.27 +    if (str.cur_bc() == Bytecodes::_monitorenter) {
   18.28 +      block->set_has_monitorenter();
   18.29 +    }
   18.30 +
   18.31      if (res) {
   18.32  
   18.33        // We have encountered a trap.  Record it in this block.
    19.1 --- a/src/share/vm/ci/ciTypeFlow.hpp	Sat Jan 21 23:02:40 2012 -0500
    19.2 +++ b/src/share/vm/ci/ciTypeFlow.hpp	Mon Jan 23 17:45:32 2012 -0800
    19.3 @@ -544,15 +544,19 @@
    19.4      // Has this block been cloned for a loop backedge?
    19.5      bool                             _backedge_copy;
    19.6  
    19.7 +    // This block is entry to irreducible loop.
    19.8 +    bool                             _irreducible_entry;
    19.9 +
   19.10 +    // This block has monitor entry point.
   19.11 +    bool                             _has_monitorenter;
   19.12 +
   19.13      // A pointer used for our internal work list
   19.14 +    bool                             _on_work_list;      // on the work list
   19.15      Block*                           _next;
   19.16 -    bool                             _on_work_list;      // on the work list
   19.17      Block*                           _rpo_next;          // Reverse post order list
   19.18  
   19.19      // Loop info
   19.20      Loop*                            _loop;              // nearest loop
   19.21 -    bool                             _irreducible_entry; // entry to irreducible loop
   19.22 -    bool                             _exception_entry;   // entry to exception handler
   19.23  
   19.24      ciBlock*     ciblock() const     { return _ciblock; }
   19.25      StateVector* state() const     { return _state; }
   19.26 @@ -689,6 +693,8 @@
   19.27      bool   is_loop_head() const          { return _loop && _loop->head() == this; }
   19.28      void   set_irreducible_entry(bool c) { _irreducible_entry = c; }
   19.29      bool   is_irreducible_entry() const  { return _irreducible_entry; }
   19.30 +    void   set_has_monitorenter()        { _has_monitorenter = true; }
   19.31 +    bool   has_monitorenter() const      { return _has_monitorenter; }
   19.32      bool   is_visited() const            { return has_pre_order(); }
   19.33      bool   is_post_visited() const       { return has_post_order(); }
   19.34      bool   is_clonable_exit(Loop* lp);
    20.1 --- a/src/share/vm/code/dependencies.cpp	Sat Jan 21 23:02:40 2012 -0500
    20.2 +++ b/src/share/vm/code/dependencies.cpp	Mon Jan 23 17:45:32 2012 -0800
    20.3 @@ -1631,7 +1631,7 @@
    20.4    for (ContextStream str(*this); str.next(); ) {
    20.5      klassOop d = str.klass();
    20.6      assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking");
    20.7 -    instanceKlass::cast(d)->set_is_marked_dependent();
    20.8 +    instanceKlass::cast(d)->set_is_marked_dependent(true);
    20.9    }
   20.10  }
   20.11  
   20.12 @@ -1640,7 +1640,7 @@
   20.13    // Unmark transitive interfaces
   20.14    for (ContextStream str(*this); str.next(); ) {
   20.15      klassOop d = str.klass();
   20.16 -    instanceKlass::cast(d)->clear_is_marked_dependent();
   20.17 +    instanceKlass::cast(d)->set_is_marked_dependent(false);
   20.18    }
   20.19  }
   20.20  
    21.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Sat Jan 21 23:02:40 2012 -0500
    21.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Jan 23 17:45:32 2012 -0800
    21.3 @@ -1,5 +1,5 @@
    21.4  /*
    21.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    21.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    21.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.8   *
    21.9   * This code is free software; you can redistribute it and/or modify it
   21.10 @@ -31,6 +31,7 @@
   21.11  #include "gc_implementation/g1/g1ErgoVerbose.hpp"
   21.12  #include "gc_implementation/g1/g1OopClosures.inline.hpp"
   21.13  #include "gc_implementation/g1/g1RemSet.hpp"
   21.14 +#include "gc_implementation/g1/heapRegion.inline.hpp"
   21.15  #include "gc_implementation/g1/heapRegionRemSet.hpp"
   21.16  #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
   21.17  #include "gc_implementation/shared/vmGCOperations.hpp"
   21.18 @@ -183,12 +184,11 @@
   21.19  void CMMarkStack::allocate(size_t size) {
   21.20    _base = NEW_C_HEAP_ARRAY(oop, size);
   21.21    if (_base == NULL) {
   21.22 -    vm_exit_during_initialization("Failed to allocate "
   21.23 -                                  "CM region mark stack");
   21.24 +    vm_exit_during_initialization("Failed to allocate CM region mark stack");
   21.25    }
   21.26    _index = 0;
   21.27    _capacity = (jint) size;
   21.28 -  _oops_do_bound = -1;
   21.29 +  _saved_index = -1;
   21.30    NOT_PRODUCT(_max_depth = 0);
   21.31  }
   21.32  
   21.33 @@ -283,7 +283,6 @@
   21.34    }
   21.35  }
   21.36  
   21.37 -
   21.38  CMRegionStack::CMRegionStack() : _base(NULL) {}
   21.39  
   21.40  void CMRegionStack::allocate(size_t size) {
   21.41 @@ -302,6 +301,8 @@
   21.42  }
   21.43  
   21.44  void CMRegionStack::push_lock_free(MemRegion mr) {
   21.45 +  guarantee(false, "push_lock_free(): don't call this any more");
   21.46 +
   21.47    assert(mr.word_size() > 0, "Precondition");
   21.48    while (true) {
   21.49      jint index = _index;
   21.50 @@ -325,6 +326,8 @@
   21.51  // marking / remark phases. Should only be called in tandem with
   21.52  // other lock-free pops.
   21.53  MemRegion CMRegionStack::pop_lock_free() {
   21.54 +  guarantee(false, "pop_lock_free(): don't call this any more");
   21.55 +
   21.56    while (true) {
   21.57      jint index = _index;
   21.58  
   21.59 @@ -390,6 +393,8 @@
   21.60  #endif
   21.61  
   21.62  bool CMRegionStack::invalidate_entries_into_cset() {
   21.63 +  guarantee(false, "invalidate_entries_into_cset(): don't call this any more");
   21.64 +
   21.65    bool result = false;
   21.66    G1CollectedHeap* g1h = G1CollectedHeap::heap();
   21.67    for (int i = 0; i < _oops_do_bound; ++i) {
   21.68 @@ -438,14 +443,29 @@
   21.69    return res;
   21.70  }
   21.71  
   21.72 +void CMMarkStack::note_start_of_gc() {
   21.73 +  assert(_saved_index == -1,
   21.74 +         "note_start_of_gc()/end_of_gc() bracketed incorrectly");
   21.75 +  _saved_index = _index;
   21.76 +}
   21.77 +
   21.78 +void CMMarkStack::note_end_of_gc() {
   21.79 +  // This is intentionally a guarantee, instead of an assert. If we
   21.80 +  // accidentally add something to the mark stack during GC, it
   21.81 +  // will be a correctness issue so it's better if we crash. we'll
   21.82 +  // only check this once per GC anyway, so it won't be a performance
   21.83 +  // issue in any way.
   21.84 +  guarantee(_saved_index == _index,
   21.85 +            err_msg("saved index: %d index: %d", _saved_index, _index));
   21.86 +  _saved_index = -1;
   21.87 +}
   21.88 +
   21.89  void CMMarkStack::oops_do(OopClosure* f) {
   21.90 -  if (_index == 0) return;
   21.91 -  assert(_oops_do_bound != -1 && _oops_do_bound <= _index,
   21.92 -         "Bound must be set.");
   21.93 -  for (int i = 0; i < _oops_do_bound; i++) {
   21.94 +  assert(_saved_index == _index,
   21.95 +         err_msg("saved index: %d index: %d", _saved_index, _index));
   21.96 +  for (int i = 0; i < _index; i += 1) {
   21.97      f->do_oop(&_base[i]);
   21.98    }
   21.99 -  _oops_do_bound = -1;
  21.100  }
  21.101  
  21.102  bool ConcurrentMark::not_yet_marked(oop obj) const {
  21.103 @@ -783,7 +803,7 @@
  21.104  public:
  21.105    bool doHeapRegion(HeapRegion* r) {
  21.106      if (!r->continuesHumongous()) {
  21.107 -      r->note_start_of_marking(true);
  21.108 +      r->note_start_of_marking();
  21.109      }
  21.110      return false;
  21.111    }
  21.112 @@ -804,6 +824,10 @@
  21.113  
  21.114    // Initialise marking structures. This has to be done in a STW phase.
  21.115    reset();
  21.116 +
  21.117 +  // For each region note start of marking.
  21.118 +  NoteStartOfMarkHRClosure startcl;
  21.119 +  g1h->heap_region_iterate(&startcl);
  21.120  }
  21.121  
  21.122  
  21.123 @@ -818,10 +842,6 @@
  21.124    // every remark and we'll eventually not need to cause one.
  21.125    force_overflow_stw()->init();
  21.126  
  21.127 -  // For each region note start of marking.
  21.128 -  NoteStartOfMarkHRClosure startcl;
  21.129 -  g1h->heap_region_iterate(&startcl);
  21.130 -
  21.131    // Start Concurrent Marking weak-reference discovery.
  21.132    ReferenceProcessor* rp = g1h->ref_processor_cm();
  21.133    // enable ("weak") refs discovery
  21.134 @@ -946,22 +966,9 @@
  21.135  }
  21.136  #endif // !PRODUCT
  21.137  
  21.138 -void ConcurrentMark::grayRoot(oop p) {
  21.139 -  HeapWord* addr = (HeapWord*) p;
  21.140 -  // We can't really check against _heap_start and _heap_end, since it
  21.141 -  // is possible during an evacuation pause with piggy-backed
  21.142 -  // initial-mark that the committed space is expanded during the
  21.143 -  // pause without CM observing this change. So the assertions below
  21.144 -  // is a bit conservative; but better than nothing.
  21.145 -  assert(_g1h->g1_committed().contains(addr),
  21.146 -         "address should be within the heap bounds");
  21.147 -
  21.148 -  if (!_nextMarkBitMap->isMarked(addr)) {
  21.149 -    _nextMarkBitMap->parMark(addr);
  21.150 -  }
  21.151 -}
  21.152 -
  21.153  void ConcurrentMark::grayRegionIfNecessary(MemRegion mr) {
  21.154 +  guarantee(false, "grayRegionIfNecessary(): don't call this any more");
  21.155 +
  21.156    // The objects on the region have already been marked "in bulk" by
  21.157    // the caller. We only need to decide whether to push the region on
  21.158    // the region stack or not.
  21.159 @@ -1007,6 +1014,8 @@
  21.160  }
  21.161  
  21.162  void ConcurrentMark::markAndGrayObjectIfNecessary(oop p) {
  21.163 +  guarantee(false, "markAndGrayObjectIfNecessary(): don't call this any more");
  21.164 +
  21.165    // The object is not marked by the caller. We need to at least mark
  21.166    // it and maybe push in on the stack.
  21.167  
  21.168 @@ -1224,7 +1233,6 @@
  21.169                                         true /* expected_active */);
  21.170  
  21.171      if (VerifyDuringGC) {
  21.172 -
  21.173        HandleMark hm;  // handle scope
  21.174        gclog_or_tty->print(" VerifyDuringGC:(after)");
  21.175        Universe::heap()->prepare_for_verify();
  21.176 @@ -1879,10 +1887,6 @@
  21.177    double end = os::elapsedTime();
  21.178    _cleanup_times.add((end - start) * 1000.0);
  21.179  
  21.180 -  // G1CollectedHeap::heap()->print();
  21.181 -  // gclog_or_tty->print_cr("HEAP GC TIME STAMP : %d",
  21.182 -  // G1CollectedHeap::heap()->get_gc_time_stamp());
  21.183 -
  21.184    if (PrintGC || PrintGCDetails) {
  21.185      g1h->print_size_transition(gclog_or_tty,
  21.186                                 start_used_bytes,
  21.187 @@ -2669,6 +2673,8 @@
  21.188  }
  21.189  
  21.190  void ConcurrentMark::drainAllSATBBuffers() {
  21.191 +  guarantee(false, "drainAllSATBBuffers(): don't call this any more");
  21.192 +
  21.193    CMGlobalObjectClosure oc(this);
  21.194    SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
  21.195    satb_mq_set.set_closure(&oc);
  21.196 @@ -2687,12 +2693,6 @@
  21.197    assert(satb_mq_set.completed_buffers_num() == 0, "invariant");
  21.198  }
  21.199  
  21.200 -void ConcurrentMark::markPrev(oop p) {
  21.201 -  // Note we are overriding the read-only view of the prev map here, via
  21.202 -  // the cast.
  21.203 -  ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*)p);
  21.204 -}
  21.205 -
  21.206  void ConcurrentMark::clear(oop p) {
  21.207    assert(p != NULL && p->is_oop(), "expected an oop");
  21.208    HeapWord* addr = (HeapWord*)p;
  21.209 @@ -2702,13 +2702,21 @@
  21.210    _nextMarkBitMap->clear(addr);
  21.211  }
  21.212  
  21.213 -void ConcurrentMark::clearRangeBothMaps(MemRegion mr) {
  21.214 +void ConcurrentMark::clearRangePrevBitmap(MemRegion mr) {
  21.215    // Note we are overriding the read-only view of the prev map here, via
  21.216    // the cast.
  21.217    ((CMBitMap*)_prevMarkBitMap)->clearRange(mr);
  21.218 +}
  21.219 +
  21.220 +void ConcurrentMark::clearRangeNextBitmap(MemRegion mr) {
  21.221    _nextMarkBitMap->clearRange(mr);
  21.222  }
  21.223  
  21.224 +void ConcurrentMark::clearRangeBothBitmaps(MemRegion mr) {
  21.225 +  clearRangePrevBitmap(mr);
  21.226 +  clearRangeNextBitmap(mr);
  21.227 +}
  21.228 +
  21.229  HeapRegion*
  21.230  ConcurrentMark::claim_region(int task_num) {
  21.231    // "checkpoint" the finger
  21.232 @@ -2803,6 +2811,9 @@
  21.233  }
  21.234  
  21.235  bool ConcurrentMark::invalidate_aborted_regions_in_cset() {
  21.236 +  guarantee(false, "invalidate_aborted_regions_in_cset(): "
  21.237 +                   "don't call this any more");
  21.238 +
  21.239    bool result = false;
  21.240    for (int i = 0; i < (int)_max_task_num; ++i) {
  21.241      CMTask* the_task = _tasks[i];
  21.242 @@ -2854,24 +2865,135 @@
  21.243      // ...then over the contents of the all the task queues.
  21.244      queue->oops_do(cl);
  21.245    }
  21.246 -
  21.247 -  // Invalidate any entries, that are in the region stack, that
  21.248 -  // point into the collection set
  21.249 -  if (_regionStack.invalidate_entries_into_cset()) {
  21.250 -    // otherwise, any gray objects copied during the evacuation pause
  21.251 -    // might not be visited.
  21.252 -    assert(_should_gray_objects, "invariant");
  21.253 +}
  21.254 +
  21.255 +#ifndef PRODUCT
  21.256 +enum VerifyNoCSetOopsPhase {
  21.257 +  VerifyNoCSetOopsStack,
  21.258 +  VerifyNoCSetOopsQueues,
  21.259 +  VerifyNoCSetOopsSATBCompleted,
  21.260 +  VerifyNoCSetOopsSATBThread
  21.261 +};
  21.262 +
  21.263 +class VerifyNoCSetOopsClosure : public OopClosure, public ObjectClosure  {
  21.264 +private:
  21.265 +  G1CollectedHeap* _g1h;
  21.266 +  VerifyNoCSetOopsPhase _phase;
  21.267 +  int _info;
  21.268 +
  21.269 +  const char* phase_str() {
  21.270 +    switch (_phase) {
  21.271 +    case VerifyNoCSetOopsStack:         return "Stack";
  21.272 +    case VerifyNoCSetOopsQueues:        return "Queue";
  21.273 +    case VerifyNoCSetOopsSATBCompleted: return "Completed SATB Buffers";
  21.274 +    case VerifyNoCSetOopsSATBThread:    return "Thread SATB Buffers";
  21.275 +    default:                            ShouldNotReachHere();
  21.276 +    }
  21.277 +    return NULL;
  21.278    }
  21.279  
  21.280 -  // Invalidate any aborted regions, recorded in the individual CM
  21.281 -  // tasks, that point into the collection set.
  21.282 -  if (invalidate_aborted_regions_in_cset()) {
  21.283 -    // otherwise, any gray objects copied during the evacuation pause
  21.284 -    // might not be visited.
  21.285 -    assert(_should_gray_objects, "invariant");
  21.286 +  void do_object_work(oop obj) {
  21.287 +    guarantee(!_g1h->obj_in_cs(obj),
  21.288 +              err_msg("obj: "PTR_FORMAT" in CSet, phase: %s, info: %d",
  21.289 +                      (void*) obj, phase_str(), _info));
  21.290    }
  21.291  
  21.292 +public:
  21.293 +  VerifyNoCSetOopsClosure() : _g1h(G1CollectedHeap::heap()) { }
  21.294 +
  21.295 +  void set_phase(VerifyNoCSetOopsPhase phase, int info = -1) {
  21.296 +    _phase = phase;
  21.297 +    _info = info;
  21.298 +  }
  21.299 +
  21.300 +  virtual void do_oop(oop* p) {
  21.301 +    oop obj = oopDesc::load_decode_heap_oop(p);
  21.302 +    do_object_work(obj);
  21.303 +  }
  21.304 +
  21.305 +  virtual void do_oop(narrowOop* p) {
  21.306 +    // We should not come across narrow oops while scanning marking
  21.307 +    // stacks and SATB buffers.
  21.308 +    ShouldNotReachHere();
  21.309 +  }
  21.310 +
  21.311 +  virtual void do_object(oop obj) {
  21.312 +    do_object_work(obj);
  21.313 +  }
  21.314 +};
  21.315 +
  21.316 +void ConcurrentMark::verify_no_cset_oops(bool verify_stacks,
  21.317 +                                         bool verify_enqueued_buffers,
  21.318 +                                         bool verify_thread_buffers,
  21.319 +                                         bool verify_fingers) {
  21.320 +  assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
  21.321 +  if (!G1CollectedHeap::heap()->mark_in_progress()) {
  21.322 +    return;
  21.323 +  }
  21.324 +
  21.325 +  VerifyNoCSetOopsClosure cl;
  21.326 +
  21.327 +  if (verify_stacks) {
  21.328 +    // Verify entries on the global mark stack
  21.329 +    cl.set_phase(VerifyNoCSetOopsStack);
  21.330 +    _markStack.oops_do(&cl);
  21.331 +
  21.332 +    // Verify entries on the task queues
  21.333 +    for (int i = 0; i < (int) _max_task_num; i += 1) {
  21.334 +      cl.set_phase(VerifyNoCSetOopsQueues, i);
  21.335 +      OopTaskQueue* queue = _task_queues->queue(i);
  21.336 +      queue->oops_do(&cl);
  21.337 +    }
  21.338 +  }
  21.339 +
  21.340 +  SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
  21.341 +
  21.342 +  // Verify entries on the enqueued SATB buffers
  21.343 +  if (verify_enqueued_buffers) {
  21.344 +    cl.set_phase(VerifyNoCSetOopsSATBCompleted);
  21.345 +    satb_qs.iterate_completed_buffers_read_only(&cl);
  21.346 +  }
  21.347 +
  21.348 +  // Verify entries on the per-thread SATB buffers
  21.349 +  if (verify_thread_buffers) {
  21.350 +    cl.set_phase(VerifyNoCSetOopsSATBThread);
  21.351 +    satb_qs.iterate_thread_buffers_read_only(&cl);
  21.352 +  }
  21.353 +
  21.354 +  if (verify_fingers) {
  21.355 +    // Verify the global finger
  21.356 +    HeapWord* global_finger = finger();
  21.357 +    if (global_finger != NULL && global_finger < _heap_end) {
  21.358 +      // The global finger always points to a heap region boundary. We
  21.359 +      // use heap_region_containing_raw() to get the containing region
  21.360 +      // given that the global finger could be pointing to a free region
  21.361 +      // which subsequently becomes continues humongous. If that
  21.362 +      // happens, heap_region_containing() will return the bottom of the
  21.363 +      // corresponding starts humongous region and the check below will
  21.364 +      // not hold any more.
  21.365 +      HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
  21.366 +      guarantee(global_finger == global_hr->bottom(),
  21.367 +                err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
  21.368 +                        global_finger, HR_FORMAT_PARAMS(global_hr)));
  21.369 +    }
  21.370 +
  21.371 +    // Verify the task fingers
  21.372 +    assert(parallel_marking_threads() <= _max_task_num, "sanity");
  21.373 +    for (int i = 0; i < (int) parallel_marking_threads(); i += 1) {
  21.374 +      CMTask* task = _tasks[i];
  21.375 +      HeapWord* task_finger = task->finger();
  21.376 +      if (task_finger != NULL && task_finger < _heap_end) {
  21.377 +        // See above note on the global finger verification.
  21.378 +        HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
  21.379 +        guarantee(task_finger == task_hr->bottom() ||
  21.380 +                  !task_hr->in_collection_set(),
  21.381 +                  err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
  21.382 +                          task_finger, HR_FORMAT_PARAMS(task_hr)));
  21.383 +      }
  21.384 +    }
  21.385 +  }
  21.386  }
  21.387 +#endif // PRODUCT
  21.388  
  21.389  void ConcurrentMark::clear_marking_state(bool clear_overflow) {
  21.390    _markStack.setEmpty();
  21.391 @@ -3080,19 +3202,6 @@
  21.392    }
  21.393  };
  21.394  
  21.395 -class SetClaimValuesInCSetHRClosure: public HeapRegionClosure {
  21.396 -  jint _claim_value;
  21.397 -
  21.398 -public:
  21.399 -  SetClaimValuesInCSetHRClosure(jint claim_value) :
  21.400 -    _claim_value(claim_value) { }
  21.401 -
  21.402 -  bool doHeapRegion(HeapRegion* hr) {
  21.403 -    hr->set_claim_value(_claim_value);
  21.404 -    return false;
  21.405 -  }
  21.406 -};
  21.407 -
  21.408  class G1ParCompleteMarkInCSetTask: public AbstractGangTask {
  21.409  protected:
  21.410    G1CollectedHeap* _g1h;
  21.411 @@ -3112,6 +3221,9 @@
  21.412  };
  21.413  
  21.414  void ConcurrentMark::complete_marking_in_collection_set() {
  21.415 +  guarantee(false, "complete_marking_in_collection_set(): "
  21.416 +                   "don't call this any more");
  21.417 +
  21.418    G1CollectedHeap* g1h =  G1CollectedHeap::heap();
  21.419  
  21.420    if (!g1h->mark_in_progress()) {
  21.421 @@ -3135,9 +3247,8 @@
  21.422  
  21.423    assert(g1h->check_cset_heap_region_claim_values(HeapRegion::CompleteMarkCSetClaimValue), "sanity");
  21.424  
  21.425 -  // Now reset the claim values in the regions in the collection set.
  21.426 -  SetClaimValuesInCSetHRClosure set_cv_cl(HeapRegion::InitialClaimValue);
  21.427 -  g1h->collection_set_iterate(&set_cv_cl);
  21.428 +  // Reset the claim values in the regions in the collection set.
  21.429 +  g1h->reset_cset_heap_region_claim_values();
  21.430  
  21.431    assert(g1h->check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
  21.432  
  21.433 @@ -3160,6 +3271,8 @@
  21.434  // newCSet().
  21.435  
  21.436  void ConcurrentMark::newCSet() {
  21.437 +  guarantee(false, "newCSet(): don't call this any more");
  21.438 +
  21.439    if (!concurrent_marking_in_progress()) {
  21.440      // nothing to do if marking is not in progress
  21.441      return;
  21.442 @@ -3198,6 +3311,8 @@
  21.443  }
  21.444  
  21.445  void ConcurrentMark::registerCSetRegion(HeapRegion* hr) {
  21.446 +  guarantee(false, "registerCSetRegion(): don't call this any more");
  21.447 +
  21.448    if (!concurrent_marking_in_progress()) return;
  21.449  
  21.450    HeapWord* region_end = hr->end();
  21.451 @@ -3209,6 +3324,9 @@
  21.452  // Resets the region fields of active CMTasks whose values point
  21.453  // into the collection set.
  21.454  void ConcurrentMark::reset_active_task_region_fields_in_cset() {
  21.455 +  guarantee(false, "reset_active_task_region_fields_in_cset(): "
  21.456 +                   "don't call this any more");
  21.457 +
  21.458    assert(SafepointSynchronize::is_at_safepoint(), "should be in STW");
  21.459    assert(parallel_marking_threads() <= _max_task_num, "sanity");
  21.460  
  21.461 @@ -3919,6 +4037,10 @@
  21.462  }
  21.463  
  21.464  void CMTask::drain_region_stack(BitMapClosure* bc) {
  21.465 +  assert(_cm->region_stack_empty(), "region stack should be empty");
  21.466 +  assert(_aborted_region.is_empty(), "aborted region should be empty");
  21.467 +  return;
  21.468 +
  21.469    if (has_aborted()) return;
  21.470  
  21.471    assert(_region_finger == NULL,
    22.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Sat Jan 21 23:02:40 2012 -0500
    22.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Mon Jan 23 17:45:32 2012 -0800
    22.3 @@ -1,5 +1,5 @@
    22.4  /*
    22.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    22.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    22.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.8   *
    22.9   * This code is free software; you can redistribute it and/or modify it
   22.10 @@ -166,10 +166,10 @@
   22.11  // Ideally this should be GrowableArray<> just like MSC's marking stack(s).
   22.12  class CMMarkStack VALUE_OBJ_CLASS_SPEC {
   22.13    ConcurrentMark* _cm;
   22.14 -  oop*   _base;      // bottom of stack
   22.15 -  jint   _index;     // one more than last occupied index
   22.16 -  jint   _capacity;  // max #elements
   22.17 -  jint   _oops_do_bound;  // Number of elements to include in next iteration.
   22.18 +  oop*   _base;        // bottom of stack
   22.19 +  jint   _index;       // one more than last occupied index
   22.20 +  jint   _capacity;    // max #elements
   22.21 +  jint   _saved_index; // value of _index saved at start of GC
   22.22    NOT_PRODUCT(jint _max_depth;)  // max depth plumbed during run
   22.23  
   22.24    bool   _overflow;
   22.25 @@ -247,16 +247,12 @@
   22.26  
   22.27    void setEmpty()   { _index = 0; clear_overflow(); }
   22.28  
   22.29 -  // Record the current size; a subsequent "oops_do" will iterate only over
   22.30 -  // indices valid at the time of this call.
   22.31 -  void set_oops_do_bound(jint bound = -1) {
   22.32 -    if (bound == -1) {
   22.33 -      _oops_do_bound = _index;
   22.34 -    } else {
   22.35 -      _oops_do_bound = bound;
   22.36 -    }
   22.37 -  }
   22.38 -  jint oops_do_bound() { return _oops_do_bound; }
   22.39 +  // Record the current index.
   22.40 +  void note_start_of_gc();
   22.41 +
   22.42 +  // Make sure that we have not added any entries to the stack during GC.
   22.43 +  void note_end_of_gc();
   22.44 +
   22.45    // iterate over the oops in the mark stack, up to the bound recorded via
   22.46    // the call above.
   22.47    void oops_do(OopClosure* f);
   22.48 @@ -724,10 +720,9 @@
   22.49    // G1CollectedHeap
   22.50  
   22.51    // This notifies CM that a root during initial-mark needs to be
   22.52 -  // grayed and it's MT-safe. Currently, we just mark it. But, in the
   22.53 -  // future, we can experiment with pushing it on the stack and we can
   22.54 -  // do this without changing G1CollectedHeap.
   22.55 -  void grayRoot(oop p);
   22.56 +  // grayed. It is MT-safe.
   22.57 +  inline void grayRoot(oop obj, size_t word_size);
   22.58 +
   22.59    // It's used during evacuation pauses to gray a region, if
   22.60    // necessary, and it's MT-safe. It assumes that the caller has
   22.61    // marked any objects on that region. If _should_gray_objects is
   22.62 @@ -735,6 +730,7 @@
   22.63    // pushed on the region stack, if it is located below the global
   22.64    // finger, otherwise we do nothing.
   22.65    void grayRegionIfNecessary(MemRegion mr);
   22.66 +
   22.67    // It's used during evacuation pauses to mark and, if necessary,
   22.68    // gray a single object and it's MT-safe. It assumes the caller did
   22.69    // not mark the object. If _should_gray_objects is true and we're
   22.70 @@ -791,24 +787,40 @@
   22.71  
   22.72    // Mark in the previous bitmap.  NB: this is usually read-only, so use
   22.73    // this carefully!
   22.74 -  void markPrev(oop p);
   22.75 +  inline void markPrev(oop p);
   22.76 +  inline void markNext(oop p);
   22.77    void clear(oop p);
   22.78 -  // Clears marks for all objects in the given range, for both prev and
   22.79 -  // next bitmaps.  NB: the previous bitmap is usually read-only, so use
   22.80 -  // this carefully!
   22.81 -  void clearRangeBothMaps(MemRegion mr);
   22.82 +  // Clears marks for all objects in the given range, for the prev,
   22.83 +  // next, or both bitmaps.  NB: the previous bitmap is usually
   22.84 +  // read-only, so use this carefully!
   22.85 +  void clearRangePrevBitmap(MemRegion mr);
   22.86 +  void clearRangeNextBitmap(MemRegion mr);
   22.87 +  void clearRangeBothBitmaps(MemRegion mr);
   22.88  
   22.89 -  // Record the current top of the mark and region stacks; a
   22.90 -  // subsequent oops_do() on the mark stack and
   22.91 -  // invalidate_entries_into_cset() on the region stack will iterate
   22.92 -  // only over indices valid at the time of this call.
   22.93 -  void set_oops_do_bound() {
   22.94 -    _markStack.set_oops_do_bound();
   22.95 -    _regionStack.set_oops_do_bound();
   22.96 +  // Notify data structures that a GC has started.
   22.97 +  void note_start_of_gc() {
   22.98 +    _markStack.note_start_of_gc();
   22.99    }
  22.100 +
  22.101 +  // Notify data structures that a GC is finished.
  22.102 +  void note_end_of_gc() {
  22.103 +    _markStack.note_end_of_gc();
  22.104 +  }
  22.105 +
  22.106    // Iterate over the oops in the mark stack and all local queues. It
  22.107    // also calls invalidate_entries_into_cset() on the region stack.
  22.108    void oops_do(OopClosure* f);
  22.109 +
  22.110 +  // Verify that there are no CSet oops on the stacks (taskqueues /
  22.111 +  // global mark stack), enqueued SATB buffers, per-thread SATB
  22.112 +  // buffers, and fingers (global / per-task). The boolean parameters
  22.113 +  // decide which of the above data structures to verify. If marking
  22.114 +  // is not in progress, it's a no-op.
  22.115 +  void verify_no_cset_oops(bool verify_stacks,
  22.116 +                           bool verify_enqueued_buffers,
  22.117 +                           bool verify_thread_buffers,
  22.118 +                           bool verify_fingers) PRODUCT_RETURN;
  22.119 +
  22.120    // It is called at the end of an evacuation pause during marking so
  22.121    // that CM is notified of where the new end of the heap is. It
  22.122    // doesn't do anything if concurrent_marking_in_progress() is false,
  22.123 @@ -1166,6 +1178,7 @@
  22.124    // It keeps picking SATB buffers and processing them until no SATB
  22.125    // buffers are available.
  22.126    void drain_satb_buffers();
  22.127 +
  22.128    // It keeps popping regions from the region stack and processing
  22.129    // them until the region stack is empty.
  22.130    void drain_region_stack(BitMapClosure* closure);
    23.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Sat Jan 21 23:02:40 2012 -0500
    23.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Mon Jan 23 17:45:32 2012 -0800
    23.3 @@ -1,5 +1,5 @@
    23.4  /*
    23.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    23.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    23.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.8   *
    23.9   * This code is free software; you can redistribute it and/or modify it
   23.10 @@ -153,4 +153,46 @@
   23.11    }
   23.12  }
   23.13  
   23.14 +inline void ConcurrentMark::markPrev(oop p) {
   23.15 +  assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
   23.16 +  // Note we are overriding the read-only view of the prev map here, via
   23.17 +  // the cast.
   23.18 +  ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
   23.19 +}
   23.20 +
   23.21 +inline void ConcurrentMark::markNext(oop p) {
   23.22 +  assert(!_nextMarkBitMap->isMarked((HeapWord*) p), "sanity");
   23.23 +  _nextMarkBitMap->mark((HeapWord*) p);
   23.24 +}
   23.25 +
   23.26 +inline void ConcurrentMark::grayRoot(oop obj, size_t word_size) {
   23.27 +  HeapWord* addr = (HeapWord*) obj;
   23.28 +
   23.29 +  // Currently we don't do anything with word_size but we will use it
   23.30 +  // in the very near future in the liveness calculation piggy-backing
   23.31 +  // changes.
   23.32 +
   23.33 +#ifdef ASSERT
   23.34 +  HeapRegion* hr = _g1h->heap_region_containing(addr);
   23.35 +  assert(hr != NULL, "sanity");
   23.36 +  assert(!hr->is_survivor(), "should not allocate survivors during IM");
   23.37 +  assert(addr < hr->next_top_at_mark_start(),
   23.38 +         err_msg("addr: "PTR_FORMAT" hr: "HR_FORMAT" NTAMS: "PTR_FORMAT,
   23.39 +                 addr, HR_FORMAT_PARAMS(hr), hr->next_top_at_mark_start()));
   23.40 +  // We cannot assert that word_size == obj->size() given that obj
   23.41 +  // might not be in a consistent state (another thread might be in
   23.42 +  // the process of copying it). So the best thing we can do is to
   23.43 +  // assert that word_size is under an upper bound which is its
   23.44 +  // containing region's capacity.
   23.45 +  assert(word_size * HeapWordSize <= hr->capacity(),
   23.46 +         err_msg("size: "SIZE_FORMAT" capacity: "SIZE_FORMAT" "HR_FORMAT,
   23.47 +                 word_size * HeapWordSize, hr->capacity(),
   23.48 +                 HR_FORMAT_PARAMS(hr)));
   23.49 +#endif // ASSERT
   23.50 +
   23.51 +  if (!_nextMarkBitMap->isMarked(addr)) {
   23.52 +    _nextMarkBitMap->parMark(addr);
   23.53 +  }
   23.54 +}
   23.55 +
   23.56  #endif // SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
    24.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Sat Jan 21 23:02:40 2012 -0500
    24.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Jan 23 17:45:32 2012 -0800
    24.3 @@ -1,5 +1,5 @@
    24.4  /*
    24.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    24.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    24.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.8   *
    24.9   * This code is free software; you can redistribute it and/or modify it
   24.10 @@ -32,9 +32,11 @@
   24.11  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
   24.12  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
   24.13  #include "gc_implementation/g1/g1ErgoVerbose.hpp"
   24.14 +#include "gc_implementation/g1/g1EvacFailure.hpp"
   24.15  #include "gc_implementation/g1/g1MarkSweep.hpp"
   24.16  #include "gc_implementation/g1/g1OopClosures.inline.hpp"
   24.17  #include "gc_implementation/g1/g1RemSet.inline.hpp"
   24.18 +#include "gc_implementation/g1/heapRegion.inline.hpp"
   24.19  #include "gc_implementation/g1/heapRegionRemSet.hpp"
   24.20  #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
   24.21  #include "gc_implementation/g1/vm_operations_g1.hpp"
   24.22 @@ -591,17 +593,29 @@
   24.23      }
   24.24      res = new_region_try_secondary_free_list();
   24.25    }
   24.26 -  if (res == NULL && do_expand) {
   24.27 +  if (res == NULL && do_expand && _expand_heap_after_alloc_failure) {
   24.28 +    // Currently, only attempts to allocate GC alloc regions set
   24.29 +    // do_expand to true. So, we should only reach here during a
   24.30 +    // safepoint. If this assumption changes we might have to
   24.31 +    // reconsider the use of _expand_heap_after_alloc_failure.
   24.32 +    assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   24.33 +
   24.34      ergo_verbose1(ErgoHeapSizing,
   24.35                    "attempt heap expansion",
   24.36                    ergo_format_reason("region allocation request failed")
   24.37                    ergo_format_byte("allocation request"),
   24.38                    word_size * HeapWordSize);
   24.39      if (expand(word_size * HeapWordSize)) {
   24.40 -      // Even though the heap was expanded, it might not have reached
   24.41 -      // the desired size. So, we cannot assume that the allocation
   24.42 -      // will succeed.
   24.43 +      // Given that expand() succeeded in expanding the heap, and we
   24.44 +      // always expand the heap by an amount aligned to the heap
   24.45 +      // region size, the free list should in theory not be empty. So
   24.46 +      // it would probably be OK to use remove_head(). But the extra
   24.47 +      // check for NULL is unlikely to be a performance issue here (we
   24.48 +      // just expanded the heap!) so let's just be conservative and
   24.49 +      // use remove_head_or_null().
   24.50        res = _free_list.remove_head_or_null();
   24.51 +    } else {
   24.52 +      _expand_heap_after_alloc_failure = false;
   24.53      }
   24.54    }
   24.55    return res;
   24.56 @@ -1838,6 +1852,7 @@
   24.57    _young_list(new YoungList(this)),
   24.58    _gc_time_stamp(0),
   24.59    _retained_old_gc_alloc_region(NULL),
   24.60 +  _expand_heap_after_alloc_failure(true),
   24.61    _surviving_young_words(NULL),
   24.62    _full_collections_completed(0),
   24.63    _in_cset_fast_test(NULL),
   24.64 @@ -2605,12 +2620,16 @@
   24.65    }
   24.66  };
   24.67  
   24.68 -void
   24.69 -G1CollectedHeap::reset_heap_region_claim_values() {
   24.70 +void G1CollectedHeap::reset_heap_region_claim_values() {
   24.71    ResetClaimValuesClosure blk;
   24.72    heap_region_iterate(&blk);
   24.73  }
   24.74  
   24.75 +void G1CollectedHeap::reset_cset_heap_region_claim_values() {
   24.76 +  ResetClaimValuesClosure blk;
   24.77 +  collection_set_iterate(&blk);
   24.78 +}
   24.79 +
   24.80  #ifdef ASSERT
   24.81  // This checks whether all regions in the heap have the correct claim
   24.82  // value. I also piggy-backed on this a check to ensure that the
   24.83 @@ -3000,14 +3019,20 @@
   24.84        } else {
   24.85          VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo);
   24.86          r->object_iterate(&not_dead_yet_cl);
   24.87 -        if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
   24.88 -          gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
   24.89 -                                 "max_live_bytes "SIZE_FORMAT" "
   24.90 -                                 "< calculated "SIZE_FORMAT,
   24.91 -                                 r->bottom(), r->end(),
   24.92 -                                 r->max_live_bytes(),
   24.93 +        if (_vo != VerifyOption_G1UseNextMarking) {
   24.94 +          if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
   24.95 +            gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
   24.96 +                                   "max_live_bytes "SIZE_FORMAT" "
   24.97 +                                   "< calculated "SIZE_FORMAT,
   24.98 +                                   r->bottom(), r->end(),
   24.99 +                                   r->max_live_bytes(),
  24.100                                   not_dead_yet_cl.live_bytes());
  24.101 -          _failures = true;
  24.102 +            _failures = true;
  24.103 +          }
  24.104 +        } else {
  24.105 +          // When vo == UseNextMarking we cannot currently do a sanity
  24.106 +          // check on the live bytes as the calculation has not been
  24.107 +          // finalized yet.
  24.108          }
  24.109        }
  24.110      }
  24.111 @@ -3641,25 +3666,6 @@
  24.112          }
  24.113          perm_gen()->save_marks();
  24.114  
  24.115 -        // We must do this before any possible evacuation that should propagate
  24.116 -        // marks.
  24.117 -        if (mark_in_progress()) {
  24.118 -          double start_time_sec = os::elapsedTime();
  24.119 -
  24.120 -          _cm->drainAllSATBBuffers();
  24.121 -          double finish_mark_ms = (os::elapsedTime() - start_time_sec) * 1000.0;
  24.122 -          g1_policy()->record_satb_drain_time(finish_mark_ms);
  24.123 -        }
  24.124 -        // Record the number of elements currently on the mark stack, so we
  24.125 -        // only iterate over these.  (Since evacuation may add to the mark
  24.126 -        // stack, doing more exposes race conditions.)  If no mark is in
  24.127 -        // progress, this will be zero.
  24.128 -        _cm->set_oops_do_bound();
  24.129 -
  24.130 -        if (mark_in_progress()) {
  24.131 -          concurrent_mark()->newCSet();
  24.132 -        }
  24.133 -
  24.134  #if YOUNG_LIST_VERBOSE
  24.135          gclog_or_tty->print_cr("\nBefore choosing collection set.\nYoung_list:");
  24.136          _young_list->print();
  24.137 @@ -3668,6 +3674,16 @@
  24.138  
  24.139          g1_policy()->choose_collection_set(target_pause_time_ms);
  24.140  
  24.141 +        _cm->note_start_of_gc();
  24.142 +        // We should not verify the per-thread SATB buffers given that
  24.143 +        // we have not filtered them yet (we'll do so during the
  24.144 +        // GC). We also call this after choose_collection_set() to
  24.145 +        // ensure that the CSet has been finalized.
  24.146 +        _cm->verify_no_cset_oops(true  /* verify_stacks */,
  24.147 +                                 true  /* verify_enqueued_buffers */,
  24.148 +                                 false /* verify_thread_buffers */,
  24.149 +                                 true  /* verify_fingers */);
  24.150 +
  24.151          if (_hr_printer.is_active()) {
  24.152            HeapRegion* hr = g1_policy()->collection_set();
  24.153            while (hr != NULL) {
  24.154 @@ -3684,16 +3700,6 @@
  24.155            }
  24.156          }
  24.157  
  24.158 -        // We have chosen the complete collection set. If marking is
  24.159 -        // active then, we clear the region fields of any of the
  24.160 -        // concurrent marking tasks whose region fields point into
  24.161 -        // the collection set as these values will become stale. This
  24.162 -        // will cause the owning marking threads to claim a new region
  24.163 -        // when marking restarts.
  24.164 -        if (mark_in_progress()) {
  24.165 -          concurrent_mark()->reset_active_task_region_fields_in_cset();
  24.166 -        }
  24.167 -
  24.168  #ifdef ASSERT
  24.169          VerifyCSetClosure cl;
  24.170          collection_set_iterate(&cl);
  24.171 @@ -3707,6 +3713,16 @@
  24.172          // Actually do the work...
  24.173          evacuate_collection_set();
  24.174  
  24.175 +        // We do this to mainly verify the per-thread SATB buffers
  24.176 +        // (which have been filtered by now) since we didn't verify
  24.177 +        // them earlier. No point in re-checking the stacks / enqueued
  24.178 +        // buffers given that the CSet has not changed since last time
  24.179 +        // we checked.
  24.180 +        _cm->verify_no_cset_oops(false /* verify_stacks */,
  24.181 +                                 false /* verify_enqueued_buffers */,
  24.182 +                                 true  /* verify_thread_buffers */,
  24.183 +                                 true  /* verify_fingers */);
  24.184 +
  24.185          free_collection_set(g1_policy()->collection_set());
  24.186          g1_policy()->clear_collection_set();
  24.187  
  24.188 @@ -3775,6 +3791,8 @@
  24.189            size_t expand_bytes = g1_policy()->expansion_amount();
  24.190            if (expand_bytes > 0) {
  24.191              size_t bytes_before = capacity();
  24.192 +            // No need for an ergo verbose message here,
  24.193 +            // expansion_amount() does this when it returns a value > 0.
  24.194              if (!expand(expand_bytes)) {
  24.195                // We failed to expand the heap so let's verify that
  24.196                // committed/uncommitted amount match the backing store
  24.197 @@ -3784,6 +3802,14 @@
  24.198            }
  24.199          }
  24.200  
  24.201 +        // We redo the verificaiton but now wrt to the new CSet which
  24.202 +        // has just got initialized after the previous CSet was freed.
  24.203 +        _cm->verify_no_cset_oops(true  /* verify_stacks */,
  24.204 +                                 true  /* verify_enqueued_buffers */,
  24.205 +                                 true  /* verify_thread_buffers */,
  24.206 +                                 true  /* verify_fingers */);
  24.207 +        _cm->note_end_of_gc();
  24.208 +
  24.209          double end_time_sec = os::elapsedTime();
  24.210          double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
  24.211          g1_policy()->record_pause_time_ms(pause_time_ms);
  24.212 @@ -3831,21 +3857,6 @@
  24.213          // CM reference discovery will be re-enabled if necessary.
  24.214        }
  24.215  
  24.216 -      {
  24.217 -        size_t expand_bytes = g1_policy()->expansion_amount();
  24.218 -        if (expand_bytes > 0) {
  24.219 -          size_t bytes_before = capacity();
  24.220 -          // No need for an ergo verbose message here,
  24.221 -          // expansion_amount() does this when it returns a value > 0.
  24.222 -          if (!expand(expand_bytes)) {
  24.223 -            // We failed to expand the heap so let's verify that
  24.224 -            // committed/uncommitted amount match the backing store
  24.225 -            assert(capacity() == _g1_storage.committed_size(), "committed size mismatch");
  24.226 -            assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch");
  24.227 -          }
  24.228 -        }
  24.229 -      }
  24.230 -
  24.231        // We should do this after we potentially expand the heap so
  24.232        // that all the COMMIT events are generated before the end GC
  24.233        // event, and after we retire the GC alloc regions so that all
  24.234 @@ -3949,6 +3960,8 @@
  24.235      // we allocate to in the region sets. We'll re-add it later, when
  24.236      // it's retired again.
  24.237      _old_set.remove(retained_region);
  24.238 +    bool during_im = g1_policy()->during_initial_mark_pause();
  24.239 +    retained_region->note_start_of_copying(during_im);
  24.240      _old_gc_alloc_region.set(retained_region);
  24.241      _hr_printer.reuse(retained_region);
  24.242    }
  24.243 @@ -3985,157 +3998,26 @@
  24.244    _evac_failure_scan_stack = NULL;
  24.245  }
  24.246  
  24.247 -class UpdateRSetDeferred : public OopsInHeapRegionClosure {
  24.248 -private:
  24.249 -  G1CollectedHeap* _g1;
  24.250 -  DirtyCardQueue *_dcq;
  24.251 -  CardTableModRefBS* _ct_bs;
  24.252 -
  24.253 -public:
  24.254 -  UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
  24.255 -    _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {}
  24.256 -
  24.257 -  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
  24.258 -  virtual void do_oop(      oop* p) { do_oop_work(p); }
  24.259 -  template <class T> void do_oop_work(T* p) {
  24.260 -    assert(_from->is_in_reserved(p), "paranoia");
  24.261 -    if (!_from->is_in_reserved(oopDesc::load_decode_heap_oop(p)) &&
  24.262 -        !_from->is_survivor()) {
  24.263 -      size_t card_index = _ct_bs->index_for(p);
  24.264 -      if (_ct_bs->mark_card_deferred(card_index)) {
  24.265 -        _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index));
  24.266 -      }
  24.267 -    }
  24.268 -  }
  24.269 -};
  24.270 -
  24.271 -class RemoveSelfPointerClosure: public ObjectClosure {
  24.272 -private:
  24.273 -  G1CollectedHeap* _g1;
  24.274 -  ConcurrentMark* _cm;
  24.275 -  HeapRegion* _hr;
  24.276 -  size_t _prev_marked_bytes;
  24.277 -  size_t _next_marked_bytes;
  24.278 -  OopsInHeapRegionClosure *_cl;
  24.279 -public:
  24.280 -  RemoveSelfPointerClosure(G1CollectedHeap* g1, HeapRegion* hr,
  24.281 -                           OopsInHeapRegionClosure* cl) :
  24.282 -    _g1(g1), _hr(hr), _cm(_g1->concurrent_mark()),  _prev_marked_bytes(0),
  24.283 -    _next_marked_bytes(0), _cl(cl) {}
  24.284 -
  24.285 -  size_t prev_marked_bytes() { return _prev_marked_bytes; }
  24.286 -  size_t next_marked_bytes() { return _next_marked_bytes; }
  24.287 -
  24.288 -  // <original comment>
  24.289 -  // The original idea here was to coalesce evacuated and dead objects.
  24.290 -  // However that caused complications with the block offset table (BOT).
  24.291 -  // In particular if there were two TLABs, one of them partially refined.
  24.292 -  // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~|
  24.293 -  // The BOT entries of the unrefined part of TLAB_2 point to the start
  24.294 -  // of TLAB_2. If the last object of the TLAB_1 and the first object
  24.295 -  // of TLAB_2 are coalesced, then the cards of the unrefined part
  24.296 -  // would point into middle of the filler object.
  24.297 -  // The current approach is to not coalesce and leave the BOT contents intact.
  24.298 -  // </original comment>
  24.299 -  //
  24.300 -  // We now reset the BOT when we start the object iteration over the
  24.301 -  // region and refine its entries for every object we come across. So
  24.302 -  // the above comment is not really relevant and we should be able
  24.303 -  // to coalesce dead objects if we want to.
  24.304 -  void do_object(oop obj) {
  24.305 -    HeapWord* obj_addr = (HeapWord*) obj;
  24.306 -    assert(_hr->is_in(obj_addr), "sanity");
  24.307 -    size_t obj_size = obj->size();
  24.308 -    _hr->update_bot_for_object(obj_addr, obj_size);
  24.309 -    if (obj->is_forwarded() && obj->forwardee() == obj) {
  24.310 -      // The object failed to move.
  24.311 -      assert(!_g1->is_obj_dead(obj), "We should not be preserving dead objs.");
  24.312 -      _cm->markPrev(obj);
  24.313 -      assert(_cm->isPrevMarked(obj), "Should be marked!");
  24.314 -      _prev_marked_bytes += (obj_size * HeapWordSize);
  24.315 -      if (_g1->mark_in_progress() && !_g1->is_obj_ill(obj)) {
  24.316 -        _cm->markAndGrayObjectIfNecessary(obj);
  24.317 -      }
  24.318 -      obj->set_mark(markOopDesc::prototype());
  24.319 -      // While we were processing RSet buffers during the
  24.320 -      // collection, we actually didn't scan any cards on the
  24.321 -      // collection set, since we didn't want to update remebered
  24.322 -      // sets with entries that point into the collection set, given
  24.323 -      // that live objects fromthe collection set are about to move
  24.324 -      // and such entries will be stale very soon. This change also
  24.325 -      // dealt with a reliability issue which involved scanning a
  24.326 -      // card in the collection set and coming across an array that
  24.327 -      // was being chunked and looking malformed. The problem is
  24.328 -      // that, if evacuation fails, we might have remembered set
  24.329 -      // entries missing given that we skipped cards on the
  24.330 -      // collection set. So, we'll recreate such entries now.
  24.331 -      obj->oop_iterate(_cl);
  24.332 -      assert(_cm->isPrevMarked(obj), "Should be marked!");
  24.333 -    } else {
  24.334 -      // The object has been either evacuated or is dead. Fill it with a
  24.335 -      // dummy object.
  24.336 -      MemRegion mr((HeapWord*)obj, obj_size);
  24.337 -      CollectedHeap::fill_with_object(mr);
  24.338 -      _cm->clearRangeBothMaps(mr);
  24.339 -    }
  24.340 -  }
  24.341 -};
  24.342 -
  24.343  void G1CollectedHeap::remove_self_forwarding_pointers() {
  24.344 -  UpdateRSetImmediate immediate_update(_g1h->g1_rem_set());
  24.345 -  DirtyCardQueue dcq(&_g1h->dirty_card_queue_set());
  24.346 -  UpdateRSetDeferred deferred_update(_g1h, &dcq);
  24.347 -  OopsInHeapRegionClosure *cl;
  24.348 -  if (G1DeferredRSUpdate) {
  24.349 -    cl = &deferred_update;
  24.350 +  assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
  24.351 +  assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!");
  24.352 +
  24.353 +  G1ParRemoveSelfForwardPtrsTask rsfp_task(this);
  24.354 +
  24.355 +  if (G1CollectedHeap::use_parallel_gc_threads()) {
  24.356 +    set_par_threads();
  24.357 +    workers()->run_task(&rsfp_task);
  24.358 +    set_par_threads(0);
  24.359    } else {
  24.360 -    cl = &immediate_update;
  24.361 -  }
  24.362 -  HeapRegion* cur = g1_policy()->collection_set();
  24.363 -  while (cur != NULL) {
  24.364 -    assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!");
  24.365 -    assert(!cur->isHumongous(), "sanity");
  24.366 -
  24.367 -    if (cur->evacuation_failed()) {
  24.368 -      assert(cur->in_collection_set(), "bad CS");
  24.369 -      RemoveSelfPointerClosure rspc(_g1h, cur, cl);
  24.370 -
  24.371 -      // In the common case we make sure that this is done when the
  24.372 -      // region is freed so that it is "ready-to-go" when it's
  24.373 -      // re-allocated. However, when evacuation failure happens, a
  24.374 -      // region will remain in the heap and might ultimately be added
  24.375 -      // to a CSet in the future. So we have to be careful here and
  24.376 -      // make sure the region's RSet is ready for parallel iteration
  24.377 -      // whenever this might be required in the future.
  24.378 -      cur->rem_set()->reset_for_par_iteration();
  24.379 -      cur->reset_bot();
  24.380 -      cl->set_region(cur);
  24.381 -      cur->object_iterate(&rspc);
  24.382 -
  24.383 -      // A number of manipulations to make the TAMS be the current top,
  24.384 -      // and the marked bytes be the ones observed in the iteration.
  24.385 -      if (_g1h->concurrent_mark()->at_least_one_mark_complete()) {
  24.386 -        // The comments below are the postconditions achieved by the
  24.387 -        // calls.  Note especially the last such condition, which says that
  24.388 -        // the count of marked bytes has been properly restored.
  24.389 -        cur->note_start_of_marking(false);
  24.390 -        // _next_top_at_mark_start == top, _next_marked_bytes == 0
  24.391 -        cur->add_to_marked_bytes(rspc.prev_marked_bytes());
  24.392 -        // _next_marked_bytes == prev_marked_bytes.
  24.393 -        cur->note_end_of_marking();
  24.394 -        // _prev_top_at_mark_start == top(),
  24.395 -        // _prev_marked_bytes == prev_marked_bytes
  24.396 -      }
  24.397 -      // If there is no mark in progress, we modified the _next variables
  24.398 -      // above needlessly, but harmlessly.
  24.399 -      if (_g1h->mark_in_progress()) {
  24.400 -        cur->note_start_of_marking(false);
  24.401 -        // _next_top_at_mark_start == top, _next_marked_bytes == 0
  24.402 -        // _next_marked_bytes == next_marked_bytes.
  24.403 -      }
  24.404 -    }
  24.405 -    cur = cur->next_in_collection_set();
  24.406 -  }
  24.407 +    rsfp_task.work(0);
  24.408 +  }
  24.409 +
  24.410 +  assert(check_cset_heap_region_claim_values(HeapRegion::ParEvacFailureClaimValue), "sanity");
  24.411 +
  24.412 +  // Reset the claim values in the regions in the collection set.
  24.413 +  reset_cset_heap_region_claim_values();
  24.414 +
  24.415 +  assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
  24.416    assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!");
  24.417  
  24.418    // Now restore saved marks, if any.
  24.419 @@ -4148,6 +4030,7 @@
  24.420        markOop m = _preserved_marks_of_objs->at(i);
  24.421        obj->set_mark(m);
  24.422      }
  24.423 +
  24.424      // Delete the preserved marks growable arrays (allocated on the C heap).
  24.425      delete _objs_with_preserved_marks;
  24.426      delete _preserved_marks_of_objs;
  24.427 @@ -4172,8 +4055,7 @@
  24.428  
  24.429  oop
  24.430  G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl,
  24.431 -                                               oop old,
  24.432 -                                               bool should_mark_root) {
  24.433 +                                               oop old) {
  24.434    assert(obj_in_cs(old),
  24.435           err_msg("obj: "PTR_FORMAT" should still be in the CSet",
  24.436                   (HeapWord*) old));
  24.437 @@ -4182,15 +4064,6 @@
  24.438    if (forward_ptr == NULL) {
  24.439      // Forward-to-self succeeded.
  24.440  
  24.441 -    // should_mark_root will be true when this routine is called
  24.442 -    // from a root scanning closure during an initial mark pause.
  24.443 -    // In this case the thread that succeeds in self-forwarding the
  24.444 -    // object is also responsible for marking the object.
  24.445 -    if (should_mark_root) {
  24.446 -      assert(!oopDesc::is_null(old), "shouldn't be");
  24.447 -      _cm->grayRoot(old);
  24.448 -    }
  24.449 -
  24.450      if (_evac_failure_closure != cl) {
  24.451        MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag);
  24.452        assert(!_drain_in_progress,
  24.453 @@ -4286,30 +4159,8 @@
  24.454    return NULL;
  24.455  }
  24.456  
  24.457 -#ifndef PRODUCT
  24.458 -bool GCLabBitMapClosure::do_bit(size_t offset) {
  24.459 -  HeapWord* addr = _bitmap->offsetToHeapWord(offset);
  24.460 -  guarantee(_cm->isMarked(oop(addr)), "it should be!");
  24.461 -  return true;
  24.462 -}
  24.463 -#endif // PRODUCT
  24.464 -
  24.465  G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
  24.466 -  ParGCAllocBuffer(gclab_word_size),
  24.467 -  _should_mark_objects(false),
  24.468 -  _bitmap(G1CollectedHeap::heap()->reserved_region().start(), gclab_word_size),
  24.469 -  _retired(false)
  24.470 -{
  24.471 -  //_should_mark_objects is set to true when G1ParCopyHelper needs to
  24.472 -  // mark the forwarded location of an evacuated object.
  24.473 -  // We set _should_mark_objects to true if marking is active, i.e. when we
  24.474 -  // need to propagate a mark, or during an initial mark pause, i.e. when we
  24.475 -  // need to mark objects immediately reachable by the roots.
  24.476 -  if (G1CollectedHeap::heap()->mark_in_progress() ||
  24.477 -      G1CollectedHeap::heap()->g1_policy()->during_initial_mark_pause()) {
  24.478 -    _should_mark_objects = true;
  24.479 -  }
  24.480 -}
  24.481 +  ParGCAllocBuffer(gclab_word_size), _retired(false) { }
  24.482  
  24.483  G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
  24.484    : _g1h(g1h),
  24.485 @@ -4323,8 +4174,7 @@
  24.486      _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)),
  24.487      _age_table(false),
  24.488      _strong_roots_time(0), _term_time(0),
  24.489 -    _alloc_buffer_waste(0), _undo_waste(0)
  24.490 -{
  24.491 +    _alloc_buffer_waste(0), _undo_waste(0) {
  24.492    // we allocate G1YoungSurvRateNumRegions plus one entries, since
  24.493    // we "sacrifice" entry 0 to keep track of surviving bytes for
  24.494    // non-young regions (where the age is -1)
  24.495 @@ -4429,35 +4279,53 @@
  24.496    } while (!refs()->is_empty());
  24.497  }
  24.498  
  24.499 -G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
  24.500 +G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1,
  24.501 +                                     G1ParScanThreadState* par_scan_state) :
  24.502    _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
  24.503    _par_scan_state(par_scan_state),
  24.504    _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()),
  24.505    _mark_in_progress(_g1->mark_in_progress()) { }
  24.506  
  24.507 -template <class T> void G1ParCopyHelper::mark_object(T* p) {
  24.508 -  // This is called from do_oop_work for objects that are not
  24.509 -  // in the collection set. Objects in the collection set
  24.510 -  // are marked after they have been evacuated.
  24.511 -
  24.512 -  T heap_oop = oopDesc::load_heap_oop(p);
  24.513 -  if (!oopDesc::is_null(heap_oop)) {
  24.514 -    oop obj = oopDesc::decode_heap_oop(heap_oop);
  24.515 -    HeapWord* addr = (HeapWord*)obj;
  24.516 -    if (_g1->is_in_g1_reserved(addr)) {
  24.517 -      _cm->grayRoot(oop(addr));
  24.518 -    }
  24.519 -  }
  24.520 -}
  24.521 -
  24.522 -oop G1ParCopyHelper::copy_to_survivor_space(oop old, bool should_mark_root,
  24.523 -                                                     bool should_mark_copy) {
  24.524 +void G1ParCopyHelper::mark_object(oop obj) {
  24.525 +#ifdef ASSERT
  24.526 +  HeapRegion* hr = _g1->heap_region_containing(obj);
  24.527 +  assert(hr != NULL, "sanity");
  24.528 +  assert(!hr->in_collection_set(), "should not mark objects in the CSet");
  24.529 +#endif // ASSERT
  24.530 +
  24.531 +  // We know that the object is not moving so it's safe to read its size.
  24.532 +  _cm->grayRoot(obj, (size_t) obj->size());
  24.533 +}
  24.534 +
  24.535 +void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
  24.536 +#ifdef ASSERT
  24.537 +  assert(from_obj->is_forwarded(), "from obj should be forwarded");
  24.538 +  assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee");
  24.539 +  assert(from_obj != to_obj, "should not be self-forwarded");
  24.540 +
  24.541 +  HeapRegion* from_hr = _g1->heap_region_containing(from_obj);
  24.542 +  assert(from_hr != NULL, "sanity");
  24.543 +  assert(from_hr->in_collection_set(), "from obj should be in the CSet");
  24.544 +
  24.545 +  HeapRegion* to_hr = _g1->heap_region_containing(to_obj);
  24.546 +  assert(to_hr != NULL, "sanity");
  24.547 +  assert(!to_hr->in_collection_set(), "should not mark objects in the CSet");
  24.548 +#endif // ASSERT
  24.549 +
  24.550 +  // The object might be in the process of being copied by another
  24.551 +  // worker so we cannot trust that its to-space image is
  24.552 +  // well-formed. So we have to read its size from its from-space
  24.553 +  // image which we know should not be changing.
  24.554 +  _cm->grayRoot(to_obj, (size_t) from_obj->size());
  24.555 +}
  24.556 +
  24.557 +oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
  24.558    size_t    word_sz = old->size();
  24.559    HeapRegion* from_region = _g1->heap_region_containing_raw(old);
  24.560    // +1 to make the -1 indexes valid...
  24.561    int       young_index = from_region->young_index_in_cset()+1;
  24.562 -  assert( (from_region->is_young() && young_index > 0) ||
  24.563 -          (!from_region->is_young() && young_index == 0), "invariant" );
  24.564 +  assert( (from_region->is_young() && young_index >  0) ||
  24.565 +         (!from_region->is_young() && young_index == 0), "invariant" );
  24.566    G1CollectorPolicy* g1p = _g1->g1_policy();
  24.567    markOop m = old->mark();
  24.568    int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
  24.569 @@ -4471,7 +4339,7 @@
  24.570      // This will either forward-to-self, or detect that someone else has
  24.571      // installed a forwarding pointer.
  24.572      OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure();
  24.573 -    return _g1->handle_evacuation_failure_par(cl, old, should_mark_root);
  24.574 +    return _g1->handle_evacuation_failure_par(cl, old);
  24.575    }
  24.576  
  24.577    // We're going to allocate linearly, so might as well prefetch ahead.
  24.578 @@ -4507,28 +4375,14 @@
  24.579        obj->set_mark(m);
  24.580      }
  24.581  
  24.582 -    // Mark the evacuated object or propagate "next" mark bit
  24.583 -    if (should_mark_copy) {
  24.584 -      if (!use_local_bitmaps ||
  24.585 -          !_par_scan_state->alloc_buffer(alloc_purpose)->mark(obj_ptr)) {
  24.586 -        // if we couldn't mark it on the local bitmap (this happens when
  24.587 -        // the object was not allocated in the GCLab), we have to bite
  24.588 -        // the bullet and do the standard parallel mark
  24.589 -        _cm->markAndGrayObjectIfNecessary(obj);
  24.590 -      }
  24.591 -
  24.592 -      if (_g1->isMarkedNext(old)) {
  24.593 -        // Unmark the object's old location so that marking
  24.594 -        // doesn't think the old object is alive.
  24.595 -        _cm->nextMarkBitMap()->parClear((HeapWord*)old);
  24.596 -      }
  24.597 -    }
  24.598 -
  24.599      size_t* surv_young_words = _par_scan_state->surviving_young_words();
  24.600      surv_young_words[young_index] += word_sz;
  24.601  
  24.602      if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
  24.603 -      arrayOop(old)->set_length(0);
  24.604 +      // We keep track of the next start index in the length field of
  24.605 +      // the to-space object. The actual length can be found in the
  24.606 +      // length field of the from-space object.
  24.607 +      arrayOop(obj)->set_length(0);
  24.608        oop* old_p = set_partial_array_mask(old);
  24.609        _par_scan_state->push_on_queue(old_p);
  24.610      } else {
  24.611 @@ -4550,61 +4404,24 @@
  24.612  ::do_oop_work(T* p) {
  24.613    oop obj = oopDesc::load_decode_heap_oop(p);
  24.614    assert(barrier != G1BarrierRS || obj != NULL,
  24.615 -         "Precondition: G1BarrierRS implies obj is nonNull");
  24.616 -
  24.617 -  // Marking:
  24.618 -  // If the object is in the collection set, then the thread
  24.619 -  // that copies the object should mark, or propagate the
  24.620 -  // mark to, the evacuated object.
  24.621 -  // If the object is not in the collection set then we
  24.622 -  // should call the mark_object() method depending on the
  24.623 -  // value of the template parameter do_mark_object (which will
  24.624 -  // be true for root scanning closures during an initial mark
  24.625 -  // pause).
  24.626 -  // The mark_object() method first checks whether the object
  24.627 -  // is marked and, if not, attempts to mark the object.
  24.628 +         "Precondition: G1BarrierRS implies obj is non-NULL");
  24.629  
  24.630    // here the null check is implicit in the cset_fast_test() test
  24.631    if (_g1->in_cset_fast_test(obj)) {
  24.632 +    oop forwardee;
  24.633      if (obj->is_forwarded()) {
  24.634 -      oopDesc::encode_store_heap_oop(p, obj->forwardee());
  24.635 -      // If we are a root scanning closure during an initial
  24.636 -      // mark pause (i.e. do_mark_object will be true) then
  24.637 -      // we also need to handle marking of roots in the
  24.638 -      // event of an evacuation failure. In the event of an
  24.639 -      // evacuation failure, the object is forwarded to itself
  24.640 -      // and not copied. For root-scanning closures, the
  24.641 -      // object would be marked after a successful self-forward
  24.642 -      // but an object could be pointed to by both a root and non
  24.643 -      // root location and be self-forwarded by a non-root-scanning
  24.644 -      // closure. Therefore we also have to attempt to mark the
  24.645 -      // self-forwarded root object here.
  24.646 -      if (do_mark_object && obj->forwardee() == obj) {
  24.647 -        mark_object(p);
  24.648 -      }
  24.649 +      forwardee = obj->forwardee();
  24.650      } else {
  24.651 -      // During an initial mark pause, objects that are pointed to
  24.652 -      // by the roots need to be marked - even in the event of an
  24.653 -      // evacuation failure. We pass the template parameter
  24.654 -      // do_mark_object (which is true for root scanning closures
  24.655 -      // during an initial mark pause) to copy_to_survivor_space
  24.656 -      // which will pass it on to the evacuation failure handling
  24.657 -      // code. The thread that successfully self-forwards a root
  24.658 -      // object to itself is responsible for marking the object.
  24.659 -      bool should_mark_root = do_mark_object;
  24.660 -
  24.661 -      // We need to mark the copied object if we're a root scanning
  24.662 -      // closure during an initial mark pause (i.e. do_mark_object
  24.663 -      // will be true), or the object is already marked and we need
  24.664 -      // to propagate the mark to the evacuated copy.
  24.665 -      bool should_mark_copy = do_mark_object ||
  24.666 -                              _during_initial_mark ||
  24.667 -                              (_mark_in_progress && !_g1->is_obj_ill(obj));
  24.668 -
  24.669 -      oop copy_oop = copy_to_survivor_space(obj, should_mark_root,
  24.670 -                                                 should_mark_copy);
  24.671 -      oopDesc::encode_store_heap_oop(p, copy_oop);
  24.672 +      forwardee = copy_to_survivor_space(obj);
  24.673      }
  24.674 +    assert(forwardee != NULL, "forwardee should not be NULL");
  24.675 +    oopDesc::encode_store_heap_oop(p, forwardee);
  24.676 +    if (do_mark_object && forwardee != obj) {
  24.677 +      // If the object is self-forwarded we don't need to explicitly
  24.678 +      // mark it, the evacuation failure protocol will do so.
  24.679 +      mark_forwarded_object(obj, forwardee);
  24.680 +    }
  24.681 +
  24.682      // When scanning the RS, we only care about objs in CS.
  24.683      if (barrier == G1BarrierRS) {
  24.684        _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
  24.685 @@ -4613,8 +4430,8 @@
  24.686      // The object is not in collection set. If we're a root scanning
  24.687      // closure during an initial mark pause (i.e. do_mark_object will
  24.688      // be true) then attempt to mark the object.
  24.689 -    if (do_mark_object) {
  24.690 -      mark_object(p);
  24.691 +    if (do_mark_object && _g1->is_in_g1_reserved(obj)) {
  24.692 +      mark_object(obj);
  24.693      }
  24.694    }
  24.695  
  24.696 @@ -4632,35 +4449,51 @@
  24.697  
  24.698  template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) {
  24.699    assert(has_partial_array_mask(p), "invariant");
  24.700 -  oop old = clear_partial_array_mask(p);
  24.701 -  assert(old->is_objArray(), "must be obj array");
  24.702 -  assert(old->is_forwarded(), "must be forwarded");
  24.703 -  assert(Universe::heap()->is_in_reserved(old), "must be in heap.");
  24.704 -
  24.705 -  objArrayOop obj = objArrayOop(old->forwardee());
  24.706 -  assert((void*)old != (void*)old->forwardee(), "self forwarding here?");
  24.707 -  // Process ParGCArrayScanChunk elements now
  24.708 -  // and push the remainder back onto queue
  24.709 -  int start     = arrayOop(old)->length();
  24.710 -  int end       = obj->length();
  24.711 -  int remainder = end - start;
  24.712 -  assert(start <= end, "just checking");
  24.713 +  oop from_obj = clear_partial_array_mask(p);
  24.714 +
  24.715 +  assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
  24.716 +  assert(from_obj->is_objArray(), "must be obj array");
  24.717 +  objArrayOop from_obj_array = objArrayOop(from_obj);
  24.718 +  // The from-space object contains the real length.
  24.719 +  int length                 = from_obj_array->length();
  24.720 +
  24.721 +  assert(from_obj->is_forwarded(), "must be forwarded");
  24.722 +  oop to_obj                 = from_obj->forwardee();
  24.723 +  assert(from_obj != to_obj, "should not be chunking self-forwarded objects");
  24.724 +  objArrayOop to_obj_array   = objArrayOop(to_obj);
  24.725 +  // We keep track of the next start index in the length field of the
  24.726 +  // to-space object.
  24.727 +  int next_index             = to_obj_array->length();
  24.728 +  assert(0 <= next_index && next_index < length,
  24.729 +         err_msg("invariant, next index: %d, length: %d", next_index, length));
  24.730 +
  24.731 +  int start                  = next_index;
  24.732 +  int end                    = length;
  24.733 +  int remainder              = end - start;
  24.734 +  // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
  24.735    if (remainder > 2 * ParGCArrayScanChunk) {
  24.736 -    // Test above combines last partial chunk with a full chunk
  24.737      end = start + ParGCArrayScanChunk;
  24.738 -    arrayOop(old)->set_length(end);
  24.739 -    // Push remainder.
  24.740 -    oop* old_p = set_partial_array_mask(old);
  24.741 -    assert(arrayOop(old)->length() < obj->length(), "Empty push?");
  24.742 -    _par_scan_state->push_on_queue(old_p);
  24.743 +    to_obj_array->set_length(end);
  24.744 +    // Push the remainder before we process the range in case another
  24.745 +    // worker has run out of things to do and can steal it.
  24.746 +    oop* from_obj_p = set_partial_array_mask(from_obj);
  24.747 +    _par_scan_state->push_on_queue(from_obj_p);
  24.748    } else {
  24.749 -    // Restore length so that the heap remains parsable in
  24.750 -    // case of evacuation failure.
  24.751 -    arrayOop(old)->set_length(end);
  24.752 -  }
  24.753 -  _scanner.set_region(_g1->heap_region_containing_raw(obj));
  24.754 -  // process our set of indices (include header in first chunk)
  24.755 -  obj->oop_iterate_range(&_scanner, start, end);
  24.756 +    assert(length == end, "sanity");
  24.757 +    // We'll process the final range for this object. Restore the length
  24.758 +    // so that the heap remains parsable in case of evacuation failure.
  24.759 +    to_obj_array->set_length(end);
  24.760 +  }
  24.761 +  _scanner.set_region(_g1->heap_region_containing_raw(to_obj));
  24.762 +  // Process indexes [start,end). It will also process the header
  24.763 +  // along with the first chunk (i.e., the chunk with start == 0).
  24.764 +  // Note that at this point the length field of to_obj_array is not
  24.765 +  // correct given that we are using it to keep track of the next
  24.766 +  // start index. oop_iterate_range() (thankfully!) ignores the length
  24.767 +  // field and only relies on the start / end parameters.  It does
  24.768 +  // however return the size of the object which will be incorrect. So
  24.769 +  // we have to ignore it even if we wanted to use it.
  24.770 +  to_obj_array->oop_iterate_range(&_scanner, start, end);
  24.771  }
  24.772  
  24.773  class G1ParEvacuateFollowersClosure : public VoidClosure {
  24.774 @@ -4893,12 +4726,16 @@
  24.775  
  24.776    g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
  24.777  
  24.778 -  // Scan strong roots in mark stack.
  24.779 -  if (!_process_strong_tasks->is_task_claimed(G1H_PS_mark_stack_oops_do)) {
  24.780 -    concurrent_mark()->oops_do(scan_non_heap_roots);
  24.781 -  }
  24.782 -  double mark_stack_scan_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
  24.783 -  g1_policy()->record_mark_stack_scan_time(worker_i, mark_stack_scan_ms);
  24.784 +  // During conc marking we have to filter the per-thread SATB buffers
  24.785 +  // to make sure we remove any oops into the CSet (which will show up
  24.786 +  // as implicitly live).
  24.787 +  if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) {
  24.788 +    if (mark_in_progress()) {
  24.789 +      JavaThread::satb_mark_queue_set().filter_thread_buffers();
  24.790 +    }
  24.791 +  }
  24.792 +  double satb_filtering_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
  24.793 +  g1_policy()->record_satb_filtering_time(worker_i, satb_filtering_ms);
  24.794  
  24.795    // Now scan the complement of the collection set.
  24.796    if (scan_rs != NULL) {
  24.797 @@ -5439,6 +5276,7 @@
  24.798  }
  24.799  
  24.800  void G1CollectedHeap::evacuate_collection_set() {
  24.801 +  _expand_heap_after_alloc_failure = true;
  24.802    set_evacuation_failed(false);
  24.803  
  24.804    g1_rem_set()->prepare_for_oops_into_collection_set_do();
  24.805 @@ -5516,13 +5354,6 @@
  24.806  
  24.807    finalize_for_evac_failure();
  24.808  
  24.809 -  // Must do this before clearing the per-region evac-failure flags
  24.810 -  // (which is currently done when we free the collection set).
  24.811 -  // We also only do this if marking is actually in progress and so
  24.812 -  // have to do this before we set the mark_in_progress flag at the
  24.813 -  // end of an initial mark pause.
  24.814 -  concurrent_mark()->complete_marking_in_collection_set();
  24.815 -
  24.816    if (evacuation_failed()) {
  24.817      remove_self_forwarding_pointers();
  24.818      if (PrintGCDetails) {
  24.819 @@ -6179,6 +6010,8 @@
  24.820        } else {
  24.821          _hr_printer.alloc(new_alloc_region, G1HRPrinter::Old);
  24.822        }
  24.823 +      bool during_im = g1_policy()->during_initial_mark_pause();
  24.824 +      new_alloc_region->note_start_of_copying(during_im);
  24.825        return new_alloc_region;
  24.826      } else {
  24.827        g1_policy()->note_alloc_region_limit_reached(ap);
  24.828 @@ -6190,7 +6023,8 @@
  24.829  void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region,
  24.830                                               size_t allocated_bytes,
  24.831                                               GCAllocPurpose ap) {
  24.832 -  alloc_region->note_end_of_copying();
  24.833 +  bool during_im = g1_policy()->during_initial_mark_pause();
  24.834 +  alloc_region->note_end_of_copying(during_im);
  24.835    g1_policy()->record_bytes_copied_during_gc(allocated_bytes);
  24.836    if (ap == GCAllocForSurvived) {
  24.837      young_list()->add_survivor_region(alloc_region);
    25.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Sat Jan 21 23:02:40 2012 -0500
    25.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Jan 23 17:45:32 2012 -0800
    25.3 @@ -1,5 +1,5 @@
    25.4  /*
    25.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    25.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    25.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.8   *
    25.9   * This code is free software; you can redistribute it and/or modify it
   25.10 @@ -285,6 +285,14 @@
   25.11    // Typically, it is not full so we should re-use it during the next GC.
   25.12    HeapRegion* _retained_old_gc_alloc_region;
   25.13  
   25.14 +  // It specifies whether we should attempt to expand the heap after a
   25.15 +  // region allocation failure. If heap expansion fails we set this to
   25.16 +  // false so that we don't re-attempt the heap expansion (it's likely
   25.17 +  // that subsequent expansion attempts will also fail if one fails).
   25.18 +  // Currently, it is only consulted during GC and it's reset at the
   25.19 +  // start of each GC.
   25.20 +  bool _expand_heap_after_alloc_failure;
   25.21 +
   25.22    // It resets the mutator alloc region before new allocations can take place.
   25.23    void init_mutator_alloc_region();
   25.24  
   25.25 @@ -861,8 +869,7 @@
   25.26    void finalize_for_evac_failure();
   25.27  
   25.28    // An attempt to evacuate "obj" has failed; take necessary steps.
   25.29 -  oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj,
   25.30 -                                    bool should_mark_root);
   25.31 +  oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj);
   25.32    void handle_evacuation_failure_common(oop obj, markOop m);
   25.33  
   25.34    // ("Weak") Reference processing support.
   25.35 @@ -954,7 +961,7 @@
   25.36    unsigned int* _worker_cset_start_region_time_stamp;
   25.37  
   25.38    enum G1H_process_strong_roots_tasks {
   25.39 -    G1H_PS_mark_stack_oops_do,
   25.40 +    G1H_PS_filter_satb_buffers,
   25.41      G1H_PS_refProcessor_oops_do,
   25.42      // Leave this one last.
   25.43      G1H_PS_NumElements
   25.44 @@ -1305,6 +1312,10 @@
   25.45    // It resets all the region claim values to the default.
   25.46    void reset_heap_region_claim_values();
   25.47  
   25.48 +  // Resets the claim values of regions in the current
   25.49 +  // collection set to the default.
   25.50 +  void reset_cset_heap_region_claim_values();
   25.51 +
   25.52  #ifdef ASSERT
   25.53    bool check_heap_region_claim_values(jint claim_value);
   25.54  
   25.55 @@ -1740,10 +1751,8 @@
   25.56        _gclab_word_size(gclab_word_size),
   25.57        _real_start_word(NULL),
   25.58        _real_end_word(NULL),
   25.59 -      _start_word(NULL)
   25.60 -  {
   25.61 -    guarantee( size_in_words() >= bitmap_size_in_words(),
   25.62 -               "just making sure");
   25.63 +      _start_word(NULL) {
   25.64 +    guarantee(false, "GCLabBitMap::GCLabBitmap(): don't call this any more");
   25.65    }
   25.66  
   25.67    inline unsigned heapWordToOffset(HeapWord* addr) {
   25.68 @@ -1797,6 +1806,8 @@
   25.69    }
   25.70  
   25.71    void set_buffer(HeapWord* start) {
   25.72 +    guarantee(false, "set_buffer(): don't call this any more");
   25.73 +
   25.74      guarantee(use_local_bitmaps, "invariant");
   25.75      clear();
   25.76  
   25.77 @@ -1820,6 +1831,8 @@
   25.78  #endif // PRODUCT
   25.79  
   25.80    void retire() {
   25.81 +    guarantee(false, "retire(): don't call this any more");
   25.82 +
   25.83      guarantee(use_local_bitmaps, "invariant");
   25.84      assert(fields_well_formed(), "invariant");
   25.85  
   25.86 @@ -1853,32 +1866,18 @@
   25.87  class G1ParGCAllocBuffer: public ParGCAllocBuffer {
   25.88  private:
   25.89    bool        _retired;
   25.90 -  bool        _should_mark_objects;
   25.91 -  GCLabBitMap _bitmap;
   25.92  
   25.93  public:
   25.94    G1ParGCAllocBuffer(size_t gclab_word_size);
   25.95  
   25.96 -  inline bool mark(HeapWord* addr) {
   25.97 -    guarantee(use_local_bitmaps, "invariant");
   25.98 -    assert(_should_mark_objects, "invariant");
   25.99 -    return _bitmap.mark(addr);
  25.100 -  }
  25.101 -
  25.102 -  inline void set_buf(HeapWord* buf) {
  25.103 -    if (use_local_bitmaps && _should_mark_objects) {
  25.104 -      _bitmap.set_buffer(buf);
  25.105 -    }
  25.106 +  void set_buf(HeapWord* buf) {
  25.107      ParGCAllocBuffer::set_buf(buf);
  25.108      _retired = false;
  25.109    }
  25.110  
  25.111 -  inline void retire(bool end_of_gc, bool retain) {
  25.112 +  void retire(bool end_of_gc, bool retain) {
  25.113      if (_retired)
  25.114        return;
  25.115 -    if (use_local_bitmaps && _should_mark_objects) {
  25.116 -      _bitmap.retire();
  25.117 -    }
  25.118      ParGCAllocBuffer::retire(end_of_gc, retain);
  25.119      _retired = true;
  25.120    }
    26.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Sat Jan 21 23:02:40 2012 -0500
    26.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Jan 23 17:45:32 2012 -0800
    26.3 @@ -1,5 +1,5 @@
    26.4  /*
    26.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    26.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    26.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.8   *
    26.9   * This code is free software; you can redistribute it and/or modify it
   26.10 @@ -281,7 +281,7 @@
   26.11  
   26.12    _par_last_gc_worker_start_times_ms = new double[_parallel_gc_threads];
   26.13    _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads];
   26.14 -  _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads];
   26.15 +  _par_last_satb_filtering_times_ms = new double[_parallel_gc_threads];
   26.16  
   26.17    _par_last_update_rs_times_ms = new double[_parallel_gc_threads];
   26.18    _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];
   26.19 @@ -905,10 +905,19 @@
   26.20      gclog_or_tty->print(" (%s)", gcs_are_young() ? "young" : "mixed");
   26.21    }
   26.22  
   26.23 -  // We only need to do this here as the policy will only be applied
   26.24 -  // to the GC we're about to start. so, no point is calculating this
   26.25 -  // every time we calculate / recalculate the target young length.
   26.26 -  update_survivors_policy();
   26.27 +  if (!during_initial_mark_pause()) {
   26.28 +    // We only need to do this here as the policy will only be applied
   26.29 +    // to the GC we're about to start. so, no point is calculating this
   26.30 +    // every time we calculate / recalculate the target young length.
   26.31 +    update_survivors_policy();
   26.32 +  } else {
   26.33 +    // The marking phase has a "we only copy implicitly live
   26.34 +    // objects during marking" invariant. The easiest way to ensure it
   26.35 +    // holds is not to allocate any survivor regions and tenure all
   26.36 +    // objects. In the future we might change this and handle survivor
   26.37 +    // regions specially during marking.
   26.38 +    tenure_all_objects();
   26.39 +  }
   26.40  
   26.41    assert(_g1->used() == _g1->recalculate_used(),
   26.42           err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
   26.43 @@ -939,7 +948,7 @@
   26.44    for (int i = 0; i < _parallel_gc_threads; ++i) {
   26.45      _par_last_gc_worker_start_times_ms[i] = -1234.0;
   26.46      _par_last_ext_root_scan_times_ms[i] = -1234.0;
   26.47 -    _par_last_mark_stack_scan_times_ms[i] = -1234.0;
   26.48 +    _par_last_satb_filtering_times_ms[i] = -1234.0;
   26.49      _par_last_update_rs_times_ms[i] = -1234.0;
   26.50      _par_last_update_rs_processed_buffers[i] = -1234.0;
   26.51      _par_last_scan_rs_times_ms[i] = -1234.0;
   26.52 @@ -1227,7 +1236,7 @@
   26.53    // of the PrintGCDetails output, in the non-parallel case.
   26.54  
   26.55    double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
   26.56 -  double mark_stack_scan_time = avg_value(_par_last_mark_stack_scan_times_ms);
   26.57 +  double satb_filtering_time = avg_value(_par_last_satb_filtering_times_ms);
   26.58    double update_rs_time = avg_value(_par_last_update_rs_times_ms);
   26.59    double update_rs_processed_buffers =
   26.60      sum_of_values(_par_last_update_rs_processed_buffers);
   26.61 @@ -1236,7 +1245,7 @@
   26.62    double termination_time = avg_value(_par_last_termination_times_ms);
   26.63  
   26.64    double known_time = ext_root_scan_time +
   26.65 -                      mark_stack_scan_time +
   26.66 +                      satb_filtering_time +
   26.67                        update_rs_time +
   26.68                        scan_rs_time +
   26.69                        obj_copy_time;
   26.70 @@ -1282,7 +1291,7 @@
   26.71      body_summary->record_satb_drain_time_ms(_cur_satb_drain_time_ms);
   26.72  
   26.73      body_summary->record_ext_root_scan_time_ms(ext_root_scan_time);
   26.74 -    body_summary->record_mark_stack_scan_time_ms(mark_stack_scan_time);
   26.75 +    body_summary->record_satb_filtering_time_ms(satb_filtering_time);
   26.76      body_summary->record_update_rs_time_ms(update_rs_time);
   26.77      body_summary->record_scan_rs_time_ms(scan_rs_time);
   26.78      body_summary->record_obj_copy_time_ms(obj_copy_time);
   26.79 @@ -1376,16 +1385,12 @@
   26.80                             (last_pause_included_initial_mark) ? " (initial-mark)" : "",
   26.81                             elapsed_ms / 1000.0);
   26.82  
   26.83 -    if (print_marking_info) {
   26.84 -      print_stats(1, "SATB Drain Time", _cur_satb_drain_time_ms);
   26.85 -    }
   26.86 -
   26.87      if (parallel) {
   26.88        print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
   26.89        print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
   26.90        print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
   26.91        if (print_marking_info) {
   26.92 -        print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms);
   26.93 +        print_par_stats(2, "SATB Filtering", _par_last_satb_filtering_times_ms);
   26.94        }
   26.95        print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
   26.96        print_par_sizes(3, "Processed Buffers", _par_last_update_rs_processed_buffers);
   26.97 @@ -1399,7 +1404,7 @@
   26.98          _par_last_gc_worker_times_ms[i] = _par_last_gc_worker_end_times_ms[i] - _par_last_gc_worker_start_times_ms[i];
   26.99  
  26.100          double worker_known_time = _par_last_ext_root_scan_times_ms[i] +
  26.101 -                                   _par_last_mark_stack_scan_times_ms[i] +
  26.102 +                                   _par_last_satb_filtering_times_ms[i] +
  26.103                                     _par_last_update_rs_times_ms[i] +
  26.104                                     _par_last_scan_rs_times_ms[i] +
  26.105                                     _par_last_obj_copy_times_ms[i] +
  26.106 @@ -1412,7 +1417,7 @@
  26.107      } else {
  26.108        print_stats(1, "Ext Root Scanning", ext_root_scan_time);
  26.109        if (print_marking_info) {
  26.110 -        print_stats(1, "Mark Stack Scanning", mark_stack_scan_time);
  26.111 +        print_stats(1, "SATB Filtering", satb_filtering_time);
  26.112        }
  26.113        print_stats(1, "Update RS", update_rs_time);
  26.114        print_stats(2, "Processed Buffers", (int)update_rs_processed_buffers);
  26.115 @@ -1983,11 +1988,10 @@
  26.116    if (summary->get_total_seq()->num() > 0) {
  26.117      print_summary_sd(0, "Evacuation Pauses", summary->get_total_seq());
  26.118      if (body_summary != NULL) {
  26.119 -      print_summary(1, "SATB Drain", body_summary->get_satb_drain_seq());
  26.120        if (parallel) {
  26.121          print_summary(1, "Parallel Time", body_summary->get_parallel_seq());
  26.122          print_summary(2, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
  26.123 -        print_summary(2, "Mark Stack Scanning", body_summary->get_mark_stack_scan_seq());
  26.124 +        print_summary(2, "SATB Filtering", body_summary->get_satb_filtering_seq());
  26.125          print_summary(2, "Update RS", body_summary->get_update_rs_seq());
  26.126          print_summary(2, "Scan RS", body_summary->get_scan_rs_seq());
  26.127          print_summary(2, "Object Copy", body_summary->get_obj_copy_seq());
  26.128 @@ -1996,7 +2000,7 @@
  26.129          {
  26.130            NumberSeq* other_parts[] = {
  26.131              body_summary->get_ext_root_scan_seq(),
  26.132 -            body_summary->get_mark_stack_scan_seq(),
  26.133 +            body_summary->get_satb_filtering_seq(),
  26.134              body_summary->get_update_rs_seq(),
  26.135              body_summary->get_scan_rs_seq(),
  26.136              body_summary->get_obj_copy_seq(),
  26.137 @@ -2009,7 +2013,7 @@
  26.138          }
  26.139        } else {
  26.140          print_summary(1, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
  26.141 -        print_summary(1, "Mark Stack Scanning", body_summary->get_mark_stack_scan_seq());
  26.142 +        print_summary(1, "SATB Filtering", body_summary->get_satb_filtering_seq());
  26.143          print_summary(1, "Update RS", body_summary->get_update_rs_seq());
  26.144          print_summary(1, "Scan RS", body_summary->get_scan_rs_seq());
  26.145          print_summary(1, "Object Copy", body_summary->get_obj_copy_seq());
  26.146 @@ -2036,7 +2040,7 @@
  26.147              body_summary->get_satb_drain_seq(),
  26.148              body_summary->get_update_rs_seq(),
  26.149              body_summary->get_ext_root_scan_seq(),
  26.150 -            body_summary->get_mark_stack_scan_seq(),
  26.151 +            body_summary->get_satb_filtering_seq(),
  26.152              body_summary->get_scan_rs_seq(),
  26.153              body_summary->get_obj_copy_seq()
  26.154            };
  26.155 @@ -2433,9 +2437,6 @@
  26.156    assert(_inc_cset_build_state == Active, "Precondition");
  26.157    assert(!hr->is_young(), "non-incremental add of young region");
  26.158  
  26.159 -  if (_g1->mark_in_progress())
  26.160 -    _g1->concurrent_mark()->registerCSetRegion(hr);
  26.161 -
  26.162    assert(!hr->in_collection_set(), "should not already be in the CSet");
  26.163    hr->set_in_collection_set(true);
  26.164    hr->set_next_in_collection_set(_collection_set);
  26.165 @@ -2705,9 +2706,6 @@
  26.166    // Clear the fields that point to the survivor list - they are all young now.
  26.167    young_list->clear_survivors();
  26.168  
  26.169 -  if (_g1->mark_in_progress())
  26.170 -    _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger);
  26.171 -
  26.172    _collection_set = _inc_cset_head;
  26.173    _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
  26.174    time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms;
    27.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Sat Jan 21 23:02:40 2012 -0500
    27.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Mon Jan 23 17:45:32 2012 -0800
    27.3 @@ -1,5 +1,5 @@
    27.4  /*
    27.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    27.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    27.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.8   *
    27.9   * This code is free software; you can redistribute it and/or modify it
   27.10 @@ -67,7 +67,7 @@
   27.11    define_num_seq(satb_drain) // optional
   27.12    define_num_seq(parallel) // parallel only
   27.13      define_num_seq(ext_root_scan)
   27.14 -    define_num_seq(mark_stack_scan)
   27.15 +    define_num_seq(satb_filtering)
   27.16      define_num_seq(update_rs)
   27.17      define_num_seq(scan_rs)
   27.18      define_num_seq(obj_copy)
   27.19 @@ -215,7 +215,7 @@
   27.20  
   27.21    double* _par_last_gc_worker_start_times_ms;
   27.22    double* _par_last_ext_root_scan_times_ms;
   27.23 -  double* _par_last_mark_stack_scan_times_ms;
   27.24 +  double* _par_last_satb_filtering_times_ms;
   27.25    double* _par_last_update_rs_times_ms;
   27.26    double* _par_last_update_rs_processed_buffers;
   27.27    double* _par_last_scan_rs_times_ms;
   27.28 @@ -841,8 +841,8 @@
   27.29      _par_last_ext_root_scan_times_ms[worker_i] = ms;
   27.30    }
   27.31  
   27.32 -  void record_mark_stack_scan_time(int worker_i, double ms) {
   27.33 -    _par_last_mark_stack_scan_times_ms[worker_i] = ms;
   27.34 +  void record_satb_filtering_time(int worker_i, double ms) {
   27.35 +    _par_last_satb_filtering_times_ms[worker_i] = ms;
   27.36    }
   27.37  
   27.38    void record_satb_drain_time(double ms) {
   27.39 @@ -1146,6 +1146,11 @@
   27.40      _survivor_surv_rate_group->stop_adding_regions();
   27.41    }
   27.42  
   27.43 +  void tenure_all_objects() {
   27.44 +    _max_survivor_regions = 0;
   27.45 +    _tenuring_threshold = 0;
   27.46 +  }
   27.47 +
   27.48    void record_survivor_regions(size_t      regions,
   27.49                                 HeapRegion* head,
   27.50                                 HeapRegion* tail) {
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp	Mon Jan 23 17:45:32 2012 -0800
    28.3 @@ -0,0 +1,236 @@
    28.4 +/*
    28.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    28.7 + *
    28.8 + * This code is free software; you can redistribute it and/or modify it
    28.9 + * under the terms of the GNU General Public License version 2 only, as
   28.10 + * published by the Free Software Foundation.
   28.11 + *
   28.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   28.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   28.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   28.15 + * version 2 for more details (a copy is included in the LICENSE file that
   28.16 + * accompanied this code).
   28.17 + *
   28.18 + * You should have received a copy of the GNU General Public License version
   28.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   28.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   28.21 + *
   28.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   28.23 + * or visit www.oracle.com if you need additional information or have any
   28.24 + * questions.
   28.25 + *
   28.26 + */
   28.27 +
   28.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1EVACFAILURE_HPP
   28.29 +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1EVACFAILURE_HPP
   28.30 +
   28.31 +#include "gc_implementation/g1/concurrentMark.inline.hpp"
   28.32 +#include "gc_implementation/g1/dirtyCardQueue.hpp"
   28.33 +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
   28.34 +#include "gc_implementation/g1/g1_globals.hpp"
   28.35 +#include "gc_implementation/g1/g1OopClosures.inline.hpp"
   28.36 +#include "gc_implementation/g1/heapRegion.hpp"
   28.37 +#include "gc_implementation/g1/heapRegionRemSet.hpp"
   28.38 +#include "utilities/workgroup.hpp"
   28.39 +
   28.40 +// Closures and tasks associated with any self-forwarding pointers
   28.41 +// installed as a result of an evacuation failure.
   28.42 +
   28.43 +class UpdateRSetDeferred : public OopsInHeapRegionClosure {
   28.44 +private:
   28.45 +  G1CollectedHeap* _g1;
   28.46 +  DirtyCardQueue *_dcq;
   28.47 +  CardTableModRefBS* _ct_bs;
   28.48 +
   28.49 +public:
   28.50 +  UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
   28.51 +    _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {}
   28.52 +
   28.53 +  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   28.54 +  virtual void do_oop(      oop* p) { do_oop_work(p); }
   28.55 +  template <class T> void do_oop_work(T* p) {
   28.56 +    assert(_from->is_in_reserved(p), "paranoia");
   28.57 +    if (!_from->is_in_reserved(oopDesc::load_decode_heap_oop(p)) &&
   28.58 +        !_from->is_survivor()) {
   28.59 +      size_t card_index = _ct_bs->index_for(p);
   28.60 +      if (_ct_bs->mark_card_deferred(card_index)) {
   28.61 +        _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index));
   28.62 +      }
   28.63 +    }
   28.64 +  }
   28.65 +};
   28.66 +
   28.67 +class RemoveSelfForwardPtrObjClosure: public ObjectClosure {
   28.68 +private:
   28.69 +  G1CollectedHeap* _g1;
   28.70 +  ConcurrentMark* _cm;
   28.71 +  HeapRegion* _hr;
   28.72 +  size_t _marked_bytes;
   28.73 +  OopsInHeapRegionClosure *_update_rset_cl;
   28.74 +  bool _during_initial_mark;
   28.75 +  bool _during_conc_mark;
   28.76 +public:
   28.77 +  RemoveSelfForwardPtrObjClosure(G1CollectedHeap* g1, ConcurrentMark* cm,
   28.78 +                                 HeapRegion* hr,
   28.79 +                                 OopsInHeapRegionClosure* update_rset_cl,
   28.80 +                                 bool during_initial_mark,
   28.81 +                                 bool during_conc_mark) :
   28.82 +    _g1(g1), _cm(cm), _hr(hr), _marked_bytes(0),
   28.83 +    _update_rset_cl(update_rset_cl),
   28.84 +    _during_initial_mark(during_initial_mark),
   28.85 +    _during_conc_mark(during_conc_mark) { }
   28.86 +
   28.87 +  size_t marked_bytes() { return _marked_bytes; }
   28.88 +
   28.89 +  // <original comment>
   28.90 +  // The original idea here was to coalesce evacuated and dead objects.
   28.91 +  // However that caused complications with the block offset table (BOT).
   28.92 +  // In particular if there were two TLABs, one of them partially refined.
   28.93 +  // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~|
   28.94 +  // The BOT entries of the unrefined part of TLAB_2 point to the start
   28.95 +  // of TLAB_2. If the last object of the TLAB_1 and the first object
   28.96 +  // of TLAB_2 are coalesced, then the cards of the unrefined part
   28.97 +  // would point into middle of the filler object.
   28.98 +  // The current approach is to not coalesce and leave the BOT contents intact.
   28.99 +  // </original comment>
  28.100 +  //
  28.101 +  // We now reset the BOT when we start the object iteration over the
  28.102 +  // region and refine its entries for every object we come across. So
  28.103 +  // the above comment is not really relevant and we should be able
  28.104 +  // to coalesce dead objects if we want to.
  28.105 +  void do_object(oop obj) {
  28.106 +    HeapWord* obj_addr = (HeapWord*) obj;
  28.107 +    assert(_hr->is_in(obj_addr), "sanity");
  28.108 +    size_t obj_size = obj->size();
  28.109 +    _hr->update_bot_for_object(obj_addr, obj_size);
  28.110 +
  28.111 +    if (obj->is_forwarded() && obj->forwardee() == obj) {
  28.112 +      // The object failed to move.
  28.113 +
  28.114 +      // We consider all objects that we find self-forwarded to be
  28.115 +      // live. What we'll do is that we'll update the prev marking
  28.116 +      // info so that they are all under PTAMS and explicitly marked.
  28.117 +      _cm->markPrev(obj);
  28.118 +      if (_during_initial_mark) {
  28.119 +        // For the next marking info we'll only mark the
  28.120 +        // self-forwarded objects explicitly if we are during
  28.121 +        // initial-mark (since, normally, we only mark objects pointed
  28.122 +        // to by roots if we succeed in copying them). By marking all
  28.123 +        // self-forwarded objects we ensure that we mark any that are
  28.124 +        // still pointed to be roots. During concurrent marking, and
  28.125 +        // after initial-mark, we don't need to mark any objects
  28.126 +        // explicitly and all objects in the CSet are considered
  28.127 +        // (implicitly) live. So, we won't mark them explicitly and
  28.128 +        // we'll leave them over NTAMS.
  28.129 +        _cm->markNext(obj);
  28.130 +      }
  28.131 +      _marked_bytes += (obj_size * HeapWordSize);
  28.132 +      obj->set_mark(markOopDesc::prototype());
  28.133 +
  28.134 +      // While we were processing RSet buffers during the collection,
  28.135 +      // we actually didn't scan any cards on the collection set,
  28.136 +      // since we didn't want to update remembered sets with entries
  28.137 +      // that point into the collection set, given that live objects
  28.138 +      // from the collection set are about to move and such entries
  28.139 +      // will be stale very soon.
  28.140 +      // This change also dealt with a reliability issue which
  28.141 +      // involved scanning a card in the collection set and coming
  28.142 +      // across an array that was being chunked and looking malformed.
  28.143 +      // The problem is that, if evacuation fails, we might have
  28.144 +      // remembered set entries missing given that we skipped cards on
  28.145 +      // the collection set. So, we'll recreate such entries now.
  28.146 +      obj->oop_iterate(_update_rset_cl);
  28.147 +      assert(_cm->isPrevMarked(obj), "Should be marked!");
  28.148 +    } else {
  28.149 +      // The object has been either evacuated or is dead. Fill it with a
  28.150 +      // dummy object.
  28.151 +      MemRegion mr((HeapWord*) obj, obj_size);
  28.152 +      CollectedHeap::fill_with_object(mr);
  28.153 +    }
  28.154 +  }
  28.155 +};
  28.156 +
  28.157 +class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
  28.158 +  G1CollectedHeap* _g1h;
  28.159 +  ConcurrentMark* _cm;
  28.160 +  OopsInHeapRegionClosure *_update_rset_cl;
  28.161 +
  28.162 +public:
  28.163 +  RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
  28.164 +                                OopsInHeapRegionClosure* update_rset_cl) :
  28.165 +    _g1h(g1h), _update_rset_cl(update_rset_cl),
  28.166 +    _cm(_g1h->concurrent_mark()) { }
  28.167 +
  28.168 +  bool doHeapRegion(HeapRegion *hr) {
  28.169 +    bool during_initial_mark = _g1h->g1_policy()->during_initial_mark_pause();
  28.170 +    bool during_conc_mark = _g1h->mark_in_progress();
  28.171 +
  28.172 +    assert(!hr->isHumongous(), "sanity");
  28.173 +    assert(hr->in_collection_set(), "bad CS");
  28.174 +
  28.175 +    if (hr->claimHeapRegion(HeapRegion::ParEvacFailureClaimValue)) {
  28.176 +      if (hr->evacuation_failed()) {
  28.177 +        RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, _update_rset_cl,
  28.178 +                                            during_initial_mark,
  28.179 +                                            during_conc_mark);
  28.180 +
  28.181 +        MemRegion mr(hr->bottom(), hr->end());
  28.182 +        // We'll recreate the prev marking info so we'll first clear
  28.183 +        // the prev bitmap range for this region. We never mark any
  28.184 +        // CSet objects explicitly so the next bitmap range should be
  28.185 +        // cleared anyway.
  28.186 +        _cm->clearRangePrevBitmap(mr);
  28.187 +
  28.188 +        hr->note_self_forwarding_removal_start(during_initial_mark,
  28.189 +                                               during_conc_mark);
  28.190 +
  28.191 +        // In the common case (i.e. when there is no evacuation
  28.192 +        // failure) we make sure that the following is done when
  28.193 +        // the region is freed so that it is "ready-to-go" when it's
  28.194 +        // re-allocated. However, when evacuation failure happens, a
  28.195 +        // region will remain in the heap and might ultimately be added
  28.196 +        // to a CSet in the future. So we have to be careful here and
  28.197 +        // make sure the region's RSet is ready for parallel iteration
  28.198 +        // whenever this might be required in the future.
  28.199 +        hr->rem_set()->reset_for_par_iteration();
  28.200 +        hr->reset_bot();
  28.201 +        _update_rset_cl->set_region(hr);
  28.202 +        hr->object_iterate(&rspc);
  28.203 +
  28.204 +        hr->note_self_forwarding_removal_end(during_initial_mark,
  28.205 +                                             during_conc_mark,
  28.206 +                                             rspc.marked_bytes());
  28.207 +      }
  28.208 +    }
  28.209 +    return false;
  28.210 +  }
  28.211 +};
  28.212 +
  28.213 +class G1ParRemoveSelfForwardPtrsTask: public AbstractGangTask {
  28.214 +protected:
  28.215 +  G1CollectedHeap* _g1h;
  28.216 +
  28.217 +public:
  28.218 +  G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h) :
  28.219 +    AbstractGangTask("G1 Remove Self-forwarding Pointers"),
  28.220 +    _g1h(g1h) { }
  28.221 +
  28.222 +  void work(uint worker_id) {
  28.223 +    UpdateRSetImmediate immediate_update(_g1h->g1_rem_set());
  28.224 +    DirtyCardQueue dcq(&_g1h->dirty_card_queue_set());
  28.225 +    UpdateRSetDeferred deferred_update(_g1h, &dcq);
  28.226 +
  28.227 +    OopsInHeapRegionClosure *update_rset_cl = &deferred_update;
  28.228 +    if (!G1DeferredRSUpdate) {
  28.229 +      update_rset_cl = &immediate_update;
  28.230 +    }
  28.231 +
  28.232 +    RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, update_rset_cl);
  28.233 +
  28.234 +    HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
  28.235 +    _g1h->collection_set_iterate_from(hr, &rsfp_cl);
  28.236 +  }
  28.237 +};
  28.238 +
  28.239 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1EVACFAILURE_HPP
    29.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Sat Jan 21 23:02:40 2012 -0500
    29.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Mon Jan 23 17:45:32 2012 -0800
    29.3 @@ -1,5 +1,5 @@
    29.4  /*
    29.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    29.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    29.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    29.8   *
    29.9   * This code is free software; you can redistribute it and/or modify it
   29.10 @@ -121,17 +121,25 @@
   29.11  class G1ParCopyHelper : public G1ParClosureSuper {
   29.12    G1ParScanClosure *_scanner;
   29.13  protected:
   29.14 -  template <class T> void mark_object(T* p);
   29.15 -  oop copy_to_survivor_space(oop obj, bool should_mark_root,
   29.16 -                                      bool should_mark_copy);
   29.17 +  // Mark the object if it's not already marked. This is used to mark
   29.18 +  // objects pointed to by roots that are guaranteed not to move
   29.19 +  // during the GC (i.e., non-CSet objects). It is MT-safe.
   29.20 +  void mark_object(oop obj);
   29.21 +
   29.22 +  // Mark the object if it's not already marked. This is used to mark
   29.23 +  // objects pointed to by roots that have been forwarded during a
   29.24 +  // GC. It is MT-safe.
   29.25 +  void mark_forwarded_object(oop from_obj, oop to_obj);
   29.26 +
   29.27 +  oop copy_to_survivor_space(oop obj);
   29.28 +
   29.29  public:
   29.30    G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
   29.31                    G1ParScanClosure *scanner) :
   29.32      G1ParClosureSuper(g1, par_scan_state), _scanner(scanner) { }
   29.33  };
   29.34  
   29.35 -template<bool do_gen_barrier, G1Barrier barrier,
   29.36 -         bool do_mark_object>
   29.37 +template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
   29.38  class G1ParCopyClosure : public G1ParCopyHelper {
   29.39    G1ParScanClosure _scanner;
   29.40  
   29.41 @@ -140,9 +148,8 @@
   29.42  public:
   29.43    G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
   29.44                     ReferenceProcessor* rp) :
   29.45 -    _scanner(g1, par_scan_state, rp),
   29.46 -    G1ParCopyHelper(g1, par_scan_state, &_scanner)
   29.47 -  {
   29.48 +      _scanner(g1, par_scan_state, rp),
   29.49 +      G1ParCopyHelper(g1, par_scan_state, &_scanner) {
   29.50      assert(_ref_processor == NULL, "sanity");
   29.51    }
   29.52  
    30.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Sat Jan 21 23:02:40 2012 -0500
    30.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Mon Jan 23 17:45:32 2012 -0800
    30.3 @@ -295,7 +295,7 @@
    30.4            "Percentage (0-100) of the heap size to use as minimum "          \
    30.5            "young gen size.")                                                \
    30.6                                                                              \
    30.7 -  develop(uintx, G1DefaultMaxNewGenPercent, 50,                             \
    30.8 +  develop(uintx, G1DefaultMaxNewGenPercent, 80,                             \
    30.9            "Percentage (0-100) of the heap size to use as maximum "          \
   30.10            "young gen size.")
   30.11  
    31.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Sat Jan 21 23:02:40 2012 -0500
    31.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Mon Jan 23 17:45:32 2012 -0800
    31.3 @@ -1,5 +1,5 @@
    31.4  /*
    31.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    31.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    31.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    31.8   *
    31.9   * This code is free software; you can redistribute it and/or modify it
   31.10 @@ -575,6 +575,40 @@
   31.11    oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl);
   31.12  }
   31.13  
   31.14 +void HeapRegion::note_self_forwarding_removal_start(bool during_initial_mark,
   31.15 +                                                    bool during_conc_mark) {
   31.16 +  // We always recreate the prev marking info and we'll explicitly
   31.17 +  // mark all objects we find to be self-forwarded on the prev
   31.18 +  // bitmap. So all objects need to be below PTAMS.
   31.19 +  _prev_top_at_mark_start = top();
   31.20 +  _prev_marked_bytes = 0;
   31.21 +
   31.22 +  if (during_initial_mark) {
   31.23 +    // During initial-mark, we'll also explicitly mark all objects
   31.24 +    // we find to be self-forwarded on the next bitmap. So all
   31.25 +    // objects need to be below NTAMS.
   31.26 +    _next_top_at_mark_start = top();
   31.27 +    set_top_at_conc_mark_count(bottom());
   31.28 +    _next_marked_bytes = 0;
   31.29 +  } else if (during_conc_mark) {
   31.30 +    // During concurrent mark, all objects in the CSet (including
   31.31 +    // the ones we find to be self-forwarded) are implicitly live.
   31.32 +    // So all objects need to be above NTAMS.
   31.33 +    _next_top_at_mark_start = bottom();
   31.34 +    set_top_at_conc_mark_count(bottom());
   31.35 +    _next_marked_bytes = 0;
   31.36 +  }
   31.37 +}
   31.38 +
   31.39 +void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark,
   31.40 +                                                  bool during_conc_mark,
   31.41 +                                                  size_t marked_bytes) {
   31.42 +  assert(0 <= marked_bytes && marked_bytes <= used(),
   31.43 +         err_msg("marked: "SIZE_FORMAT" used: "SIZE_FORMAT,
   31.44 +                 marked_bytes, used()));
   31.45 +  _prev_marked_bytes = marked_bytes;
   31.46 +}
   31.47 +
   31.48  HeapWord*
   31.49  HeapRegion::object_iterate_mem_careful(MemRegion mr,
   31.50                                                   ObjectClosure* cl) {
    32.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Sat Jan 21 23:02:40 2012 -0500
    32.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Mon Jan 23 17:45:32 2012 -0800
    32.3 @@ -1,5 +1,5 @@
    32.4  /*
    32.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    32.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    32.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    32.8   *
    32.9   * This code is free software; you can redistribute it and/or modify it
   32.10 @@ -373,7 +373,8 @@
   32.11      ScrubRemSetClaimValue      = 3,
   32.12      ParVerifyClaimValue        = 4,
   32.13      RebuildRSClaimValue        = 5,
   32.14 -    CompleteMarkCSetClaimValue = 6
   32.15 +    CompleteMarkCSetClaimValue = 6,
   32.16 +    ParEvacFailureClaimValue   = 7
   32.17    };
   32.18  
   32.19    inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
   32.20 @@ -582,37 +583,33 @@
   32.21    // that the collector is about to start or has finished (concurrently)
   32.22    // marking the heap.
   32.23  
   32.24 -  // Note the start of a marking phase. Record the
   32.25 -  // start of the unmarked area of the region here.
   32.26 -  void note_start_of_marking(bool during_initial_mark) {
   32.27 -    init_top_at_conc_mark_count();
   32.28 -    _next_marked_bytes = 0;
   32.29 -    if (during_initial_mark && is_young() && !is_survivor())
   32.30 -      _next_top_at_mark_start = bottom();
   32.31 -    else
   32.32 -      _next_top_at_mark_start = top();
   32.33 -  }
   32.34 +  // Notify the region that concurrent marking is starting. Initialize
   32.35 +  // all fields related to the next marking info.
   32.36 +  inline void note_start_of_marking();
   32.37  
   32.38 -  // Note the end of a marking phase. Install the start of
   32.39 -  // the unmarked area that was captured at start of marking.
   32.40 -  void note_end_of_marking() {
   32.41 -    _prev_top_at_mark_start = _next_top_at_mark_start;
   32.42 -    _prev_marked_bytes = _next_marked_bytes;
   32.43 -    _next_marked_bytes = 0;
   32.44 +  // Notify the region that concurrent marking has finished. Copy the
   32.45 +  // (now finalized) next marking info fields into the prev marking
   32.46 +  // info fields.
   32.47 +  inline void note_end_of_marking();
   32.48  
   32.49 -    guarantee(_prev_marked_bytes <=
   32.50 -              (size_t) (prev_top_at_mark_start() - bottom()) * HeapWordSize,
   32.51 -              "invariant");
   32.52 -  }
   32.53 +  // Notify the region that it will be used as to-space during a GC
   32.54 +  // and we are about to start copying objects into it.
   32.55 +  inline void note_start_of_copying(bool during_initial_mark);
   32.56  
   32.57 -  // After an evacuation, we need to update _next_top_at_mark_start
   32.58 -  // to be the current top.  Note this is only valid if we have only
   32.59 -  // ever evacuated into this region.  If we evacuate, allocate, and
   32.60 -  // then evacuate we are in deep doodoo.
   32.61 -  void note_end_of_copying() {
   32.62 -    assert(top() >= _next_top_at_mark_start, "Increase only");
   32.63 -    _next_top_at_mark_start = top();
   32.64 -  }
   32.65 +  // Notify the region that it ceases being to-space during a GC and
   32.66 +  // we will not copy objects into it any more.
   32.67 +  inline void note_end_of_copying(bool during_initial_mark);
   32.68 +
   32.69 +  // Notify the region that we are about to start processing
   32.70 +  // self-forwarded objects during evac failure handling.
   32.71 +  void note_self_forwarding_removal_start(bool during_initial_mark,
   32.72 +                                          bool during_conc_mark);
   32.73 +
   32.74 +  // Notify the region that we have finished processing self-forwarded
   32.75 +  // objects during evac failure handling.
   32.76 +  void note_self_forwarding_removal_end(bool during_initial_mark,
   32.77 +                                        bool during_conc_mark,
   32.78 +                                        size_t marked_bytes);
   32.79  
   32.80    // Returns "false" iff no object in the region was allocated when the
   32.81    // last mark phase ended.
    33.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp	Sat Jan 21 23:02:40 2012 -0500
    33.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp	Mon Jan 23 17:45:32 2012 -0800
    33.3 @@ -1,5 +1,5 @@
    33.4  /*
    33.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
    33.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    33.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    33.8   *
    33.9   * This code is free software; you can redistribute it and/or modify it
   33.10 @@ -55,4 +55,71 @@
   33.11    return _offsets.block_start_const(p);
   33.12  }
   33.13  
   33.14 +inline void HeapRegion::note_start_of_marking() {
   33.15 +  init_top_at_conc_mark_count();
   33.16 +  _next_marked_bytes = 0;
   33.17 +  _next_top_at_mark_start = top();
   33.18 +}
   33.19 +
   33.20 +inline void HeapRegion::note_end_of_marking() {
   33.21 +  _prev_top_at_mark_start = _next_top_at_mark_start;
   33.22 +  _prev_marked_bytes = _next_marked_bytes;
   33.23 +  _next_marked_bytes = 0;
   33.24 +
   33.25 +  assert(_prev_marked_bytes <=
   33.26 +         (size_t) pointer_delta(prev_top_at_mark_start(), bottom()) *
   33.27 +         HeapWordSize, "invariant");
   33.28 +}
   33.29 +
   33.30 +inline void HeapRegion::note_start_of_copying(bool during_initial_mark) {
   33.31 +  if (during_initial_mark) {
   33.32 +    if (is_survivor()) {
   33.33 +      assert(false, "should not allocate survivors during IM");
   33.34 +    } else {
   33.35 +      // During initial-mark we'll explicitly mark any objects on old
   33.36 +      // regions that are pointed to by roots. Given that explicit
   33.37 +      // marks only make sense under NTAMS it'd be nice if we could
   33.38 +      // check that condition if we wanted to. Given that we don't
   33.39 +      // know where the top of this region will end up, we simply set
   33.40 +      // NTAMS to the end of the region so all marks will be below
   33.41 +      // NTAMS. We'll set it to the actual top when we retire this region.
   33.42 +      _next_top_at_mark_start = end();
   33.43 +    }
   33.44 +  } else {
   33.45 +    if (is_survivor()) {
   33.46 +      // This is how we always allocate survivors.
   33.47 +      assert(_next_top_at_mark_start == bottom(), "invariant");
   33.48 +    } else {
   33.49 +      // We could have re-used this old region as to-space over a
   33.50 +      // couple of GCs since the start of the concurrent marking
   33.51 +      // cycle. This means that [bottom,NTAMS) will contain objects
   33.52 +      // copied up to and including initial-mark and [NTAMS, top)
   33.53 +      // will contain objects copied during the concurrent marking cycle.
   33.54 +      assert(top() >= _next_top_at_mark_start, "invariant");
   33.55 +    }
   33.56 +  }
   33.57 +}
   33.58 +
   33.59 +inline void HeapRegion::note_end_of_copying(bool during_initial_mark) {
   33.60 +  if (during_initial_mark) {
   33.61 +    if (is_survivor()) {
   33.62 +      assert(false, "should not allocate survivors during IM");
   33.63 +    } else {
   33.64 +      // See the comment for note_start_of_copying() for the details
   33.65 +      // on this.
   33.66 +      assert(_next_top_at_mark_start == end(), "pre-condition");
   33.67 +      _next_top_at_mark_start = top();
   33.68 +    }
   33.69 +  } else {
   33.70 +    if (is_survivor()) {
   33.71 +      // This is how we always allocate survivors.
   33.72 +      assert(_next_top_at_mark_start == bottom(), "invariant");
   33.73 +    } else {
   33.74 +      // See the comment for note_start_of_copying() for the details
   33.75 +      // on this.
   33.76 +      assert(top() >= _next_top_at_mark_start, "invariant");
   33.77 +    }
   33.78 +  }
   33.79 +}
   33.80 +
   33.81  #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP
    34.1 --- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Sat Jan 21 23:02:40 2012 -0500
    34.2 +++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Mon Jan 23 17:45:32 2012 -0800
    34.3 @@ -1,5 +1,5 @@
    34.4  /*
    34.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    34.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. 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 @@ -70,7 +70,7 @@
   34.11    // given PtrQueueSet.
   34.12    PtrQueue(PtrQueueSet* qset, bool perm = false, bool active = false);
   34.13    // Release any contained resources.
   34.14 -  void flush();
   34.15 +  virtual void flush();
   34.16    // Calls flush() when destroyed.
   34.17    ~PtrQueue() { flush(); }
   34.18  
    35.1 --- a/src/share/vm/gc_implementation/g1/satbQueue.cpp	Sat Jan 21 23:02:40 2012 -0500
    35.2 +++ b/src/share/vm/gc_implementation/g1/satbQueue.cpp	Mon Jan 23 17:45:32 2012 -0800
    35.3 @@ -1,5 +1,5 @@
    35.4  /*
    35.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    35.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. 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 @@ -31,6 +31,14 @@
   35.11  #include "runtime/thread.hpp"
   35.12  #include "runtime/vmThread.hpp"
   35.13  
   35.14 +void ObjPtrQueue::flush() {
   35.15 +  // The buffer might contain refs into the CSet. We have to filter it
   35.16 +  // first before we flush it, otherwise we might end up with an
   35.17 +  // enqueued buffer with refs into the CSet which breaks our invariants.
   35.18 +  filter();
   35.19 +  PtrQueue::flush();
   35.20 +}
   35.21 +
   35.22  // This method removes entries from an SATB buffer that will not be
   35.23  // useful to the concurrent marking threads. An entry is removed if it
   35.24  // satisfies one of the following conditions:
   35.25 @@ -44,38 +52,27 @@
   35.26  //     process it again).
   35.27  //
   35.28  // The rest of the entries will be retained and are compacted towards
   35.29 -// the top of the buffer. If with this filtering we clear a large
   35.30 -// enough chunk of the buffer we can re-use it (instead of enqueueing
   35.31 -// it) and we can just allow the mutator to carry on executing.
   35.32 +// the top of the buffer. Note that, because we do not allow old
   35.33 +// regions in the CSet during marking, all objects on the CSet regions
   35.34 +// are young (eden or survivors) and therefore implicitly live. So any
   35.35 +// references into the CSet will be removed during filtering.
   35.36  
   35.37 -bool ObjPtrQueue::should_enqueue_buffer() {
   35.38 -  assert(_lock == NULL || _lock->owned_by_self(),
   35.39 -         "we should have taken the lock before calling this");
   35.40 -
   35.41 -  // A value of 0 means "don't filter SATB buffers".
   35.42 -  if (G1SATBBufferEnqueueingThresholdPercent == 0) {
   35.43 -    return true;
   35.44 -  }
   35.45 -
   35.46 +void ObjPtrQueue::filter() {
   35.47    G1CollectedHeap* g1h = G1CollectedHeap::heap();
   35.48 -
   35.49 -  // This method should only be called if there is a non-NULL buffer
   35.50 -  // that is full.
   35.51 -  assert(_index == 0, "pre-condition");
   35.52 -  assert(_buf != NULL, "pre-condition");
   35.53 -
   35.54    void** buf = _buf;
   35.55    size_t sz = _sz;
   35.56  
   35.57 +  if (buf == NULL) {
   35.58 +    // nothing to do
   35.59 +    return;
   35.60 +  }
   35.61 +
   35.62    // Used for sanity checking at the end of the loop.
   35.63    debug_only(size_t entries = 0; size_t retained = 0;)
   35.64  
   35.65    size_t i = sz;
   35.66    size_t new_index = sz;
   35.67  
   35.68 -  // Given that we are expecting _index == 0, we could have changed
   35.69 -  // the loop condition to (i > 0). But we are using _index for
   35.70 -  // generality.
   35.71    while (i > _index) {
   35.72      assert(i > 0, "we should have at least one more entry to process");
   35.73      i -= oopSize;
   35.74 @@ -103,22 +100,58 @@
   35.75        debug_only(retained += 1;)
   35.76      }
   35.77    }
   35.78 +
   35.79 +#ifdef ASSERT
   35.80    size_t entries_calc = (sz - _index) / oopSize;
   35.81    assert(entries == entries_calc, "the number of entries we counted "
   35.82           "should match the number of entries we calculated");
   35.83    size_t retained_calc = (sz - new_index) / oopSize;
   35.84    assert(retained == retained_calc, "the number of retained entries we counted "
   35.85           "should match the number of retained entries we calculated");
   35.86 -  size_t perc = retained_calc * 100 / entries_calc;
   35.87 +#endif // ASSERT
   35.88 +
   35.89 +  _index = new_index;
   35.90 +}
   35.91 +
   35.92 +// This method will first apply the above filtering to the buffer. If
   35.93 +// post-filtering a large enough chunk of the buffer has been cleared
   35.94 +// we can re-use the buffer (instead of enqueueing it) and we can just
   35.95 +// allow the mutator to carry on executing using the same buffer
   35.96 +// instead of replacing it.
   35.97 +
   35.98 +bool ObjPtrQueue::should_enqueue_buffer() {
   35.99 +  assert(_lock == NULL || _lock->owned_by_self(),
  35.100 +         "we should have taken the lock before calling this");
  35.101 +
  35.102 +  // Even if G1SATBBufferEnqueueingThresholdPercent == 0 we have to
  35.103 +  // filter the buffer given that this will remove any references into
  35.104 +  // the CSet as we currently assume that no such refs will appear in
  35.105 +  // enqueued buffers.
  35.106 +
  35.107 +  // This method should only be called if there is a non-NULL buffer
  35.108 +  // that is full.
  35.109 +  assert(_index == 0, "pre-condition");
  35.110 +  assert(_buf != NULL, "pre-condition");
  35.111 +
  35.112 +  filter();
  35.113 +
  35.114 +  size_t sz = _sz;
  35.115 +  size_t all_entries = sz / oopSize;
  35.116 +  size_t retained_entries = (sz - _index) / oopSize;
  35.117 +  size_t perc = retained_entries * 100 / all_entries;
  35.118    bool should_enqueue = perc > (size_t) G1SATBBufferEnqueueingThresholdPercent;
  35.119 -  _index = new_index;
  35.120 -
  35.121    return should_enqueue;
  35.122  }
  35.123  
  35.124  void ObjPtrQueue::apply_closure(ObjectClosure* cl) {
  35.125    if (_buf != NULL) {
  35.126      apply_closure_to_buffer(cl, _buf, _index, _sz);
  35.127 +  }
  35.128 +}
  35.129 +
  35.130 +void ObjPtrQueue::apply_closure_and_empty(ObjectClosure* cl) {
  35.131 +  if (_buf != NULL) {
  35.132 +    apply_closure_to_buffer(cl, _buf, _index, _sz);
  35.133      _index = _sz;
  35.134    }
  35.135  }
  35.136 @@ -135,6 +168,21 @@
  35.137    }
  35.138  }
  35.139  
  35.140 +#ifndef PRODUCT
  35.141 +// Helpful for debugging
  35.142 +
  35.143 +void ObjPtrQueue::print(const char* name) {
  35.144 +  print(name, _buf, _index, _sz);
  35.145 +}
  35.146 +
  35.147 +void ObjPtrQueue::print(const char* name,
  35.148 +                        void** buf, size_t index, size_t sz) {
  35.149 +  gclog_or_tty->print_cr("  SATB BUFFER [%s] buf: "PTR_FORMAT" "
  35.150 +                         "index: "SIZE_FORMAT" sz: "SIZE_FORMAT,
  35.151 +                         name, buf, index, sz);
  35.152 +}
  35.153 +#endif // PRODUCT
  35.154 +
  35.155  #ifdef ASSERT
  35.156  void ObjPtrQueue::verify_oops_in_buffer() {
  35.157    if (_buf == NULL) return;
  35.158 @@ -150,12 +198,9 @@
  35.159  #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
  35.160  #endif // _MSC_VER
  35.161  
  35.162 -
  35.163  SATBMarkQueueSet::SATBMarkQueueSet() :
  35.164 -  PtrQueueSet(),
  35.165 -  _closure(NULL), _par_closures(NULL),
  35.166 -  _shared_satb_queue(this, true /*perm*/)
  35.167 -{}
  35.168 +  PtrQueueSet(), _closure(NULL), _par_closures(NULL),
  35.169 +  _shared_satb_queue(this, true /*perm*/) { }
  35.170  
  35.171  void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
  35.172                                    int process_completed_threshold,
  35.173 @@ -167,7 +212,6 @@
  35.174    }
  35.175  }
  35.176  
  35.177 -
  35.178  void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
  35.179    DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();)
  35.180    t->satb_mark_queue().handle_zero_index();
  35.181 @@ -228,6 +272,13 @@
  35.182    }
  35.183  }
  35.184  
  35.185 +void SATBMarkQueueSet::filter_thread_buffers() {
  35.186 +  for(JavaThread* t = Threads::first(); t; t = t->next()) {
  35.187 +    t->satb_mark_queue().filter();
  35.188 +  }
  35.189 +  shared_satb_queue()->filter();
  35.190 +}
  35.191 +
  35.192  void SATBMarkQueueSet::set_closure(ObjectClosure* closure) {
  35.193    _closure = closure;
  35.194  }
  35.195 @@ -239,9 +290,9 @@
  35.196  
  35.197  void SATBMarkQueueSet::iterate_closure_all_threads() {
  35.198    for(JavaThread* t = Threads::first(); t; t = t->next()) {
  35.199 -    t->satb_mark_queue().apply_closure(_closure);
  35.200 +    t->satb_mark_queue().apply_closure_and_empty(_closure);
  35.201    }
  35.202 -  shared_satb_queue()->apply_closure(_closure);
  35.203 +  shared_satb_queue()->apply_closure_and_empty(_closure);
  35.204  }
  35.205  
  35.206  void SATBMarkQueueSet::par_iterate_closure_all_threads(int worker) {
  35.207 @@ -250,7 +301,7 @@
  35.208  
  35.209    for(JavaThread* t = Threads::first(); t; t = t->next()) {
  35.210      if (t->claim_oops_do(true, parity)) {
  35.211 -      t->satb_mark_queue().apply_closure(_par_closures[worker]);
  35.212 +      t->satb_mark_queue().apply_closure_and_empty(_par_closures[worker]);
  35.213      }
  35.214    }
  35.215  
  35.216 @@ -264,7 +315,7 @@
  35.217  
  35.218    VMThread* vmt = VMThread::vm_thread();
  35.219    if (vmt->claim_oops_do(true, parity)) {
  35.220 -    shared_satb_queue()->apply_closure(_par_closures[worker]);
  35.221 +    shared_satb_queue()->apply_closure_and_empty(_par_closures[worker]);
  35.222    }
  35.223  }
  35.224  
  35.225 @@ -292,6 +343,61 @@
  35.226    }
  35.227  }
  35.228  
  35.229 +void SATBMarkQueueSet::iterate_completed_buffers_read_only(ObjectClosure* cl) {
  35.230 +  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
  35.231 +  assert(cl != NULL, "pre-condition");
  35.232 +
  35.233 +  BufferNode* nd = _completed_buffers_head;
  35.234 +  while (nd != NULL) {
  35.235 +    void** buf = BufferNode::make_buffer_from_node(nd);
  35.236 +    ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
  35.237 +    nd = nd->next();
  35.238 +  }
  35.239 +}
  35.240 +
  35.241 +void SATBMarkQueueSet::iterate_thread_buffers_read_only(ObjectClosure* cl) {
  35.242 +  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
  35.243 +  assert(cl != NULL, "pre-condition");
  35.244 +
  35.245 +  for (JavaThread* t = Threads::first(); t; t = t->next()) {
  35.246 +    t->satb_mark_queue().apply_closure(cl);
  35.247 +  }
  35.248 +  shared_satb_queue()->apply_closure(cl);
  35.249 +}
  35.250 +
  35.251 +#ifndef PRODUCT
  35.252 +// Helpful for debugging
  35.253 +
  35.254 +#define SATB_PRINTER_BUFFER_SIZE 256
  35.255 +
  35.256 +void SATBMarkQueueSet::print_all(const char* msg) {
  35.257 +  char buffer[SATB_PRINTER_BUFFER_SIZE];
  35.258 +  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
  35.259 +
  35.260 +  gclog_or_tty->cr();
  35.261 +  gclog_or_tty->print_cr("SATB BUFFERS [%s]", msg);
  35.262 +
  35.263 +  BufferNode* nd = _completed_buffers_head;
  35.264 +  int i = 0;
  35.265 +  while (nd != NULL) {
  35.266 +    void** buf = BufferNode::make_buffer_from_node(nd);
  35.267 +    jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Enqueued: %d", i);
  35.268 +    ObjPtrQueue::print(buffer, buf, 0, _sz);
  35.269 +    nd = nd->next();
  35.270 +    i += 1;
  35.271 +  }
  35.272 +
  35.273 +  for (JavaThread* t = Threads::first(); t; t = t->next()) {
  35.274 +    jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
  35.275 +    t->satb_mark_queue().print(buffer);
  35.276 +  }
  35.277 +
  35.278 +  shared_satb_queue()->print("Shared");
  35.279 +
  35.280 +  gclog_or_tty->cr();
  35.281 +}
  35.282 +#endif // PRODUCT
  35.283 +
  35.284  void SATBMarkQueueSet::abandon_partial_marking() {
  35.285    BufferNode* buffers_to_delete = NULL;
  35.286    {
  35.287 @@ -316,5 +422,5 @@
  35.288    for (JavaThread* t = Threads::first(); t; t = t->next()) {
  35.289      t->satb_mark_queue().reset();
  35.290    }
  35.291 -  shared_satb_queue()->reset();
  35.292 + shared_satb_queue()->reset();
  35.293  }
    36.1 --- a/src/share/vm/gc_implementation/g1/satbQueue.hpp	Sat Jan 21 23:02:40 2012 -0500
    36.2 +++ b/src/share/vm/gc_implementation/g1/satbQueue.hpp	Mon Jan 23 17:45:32 2012 -0800
    36.3 @@ -1,5 +1,5 @@
    36.4  /*
    36.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    36.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. 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 @@ -29,9 +29,26 @@
   36.11  
   36.12  class ObjectClosure;
   36.13  class JavaThread;
   36.14 +class SATBMarkQueueSet;
   36.15  
   36.16  // A ptrQueue whose elements are "oops", pointers to object heads.
   36.17  class ObjPtrQueue: public PtrQueue {
   36.18 +  friend class SATBMarkQueueSet;
   36.19 +
   36.20 +private:
   36.21 +  // Filter out unwanted entries from the buffer.
   36.22 +  void filter();
   36.23 +
   36.24 +  // Apply the closure to all elements.
   36.25 +  void apply_closure(ObjectClosure* cl);
   36.26 +
   36.27 +  // Apply the closure to all elements and empty the buffer;
   36.28 +  void apply_closure_and_empty(ObjectClosure* cl);
   36.29 +
   36.30 +  // Apply the closure to all elements of "buf", down to "index" (inclusive.)
   36.31 +  static void apply_closure_to_buffer(ObjectClosure* cl,
   36.32 +                                      void** buf, size_t index, size_t sz);
   36.33 +
   36.34  public:
   36.35    ObjPtrQueue(PtrQueueSet* qset, bool perm = false) :
   36.36      // SATB queues are only active during marking cycles. We create
   36.37 @@ -41,23 +58,23 @@
   36.38      // field to true. This is done in JavaThread::initialize_queues().
   36.39      PtrQueue(qset, perm, false /* active */) { }
   36.40  
   36.41 +  // Overrides PtrQueue::flush() so that it can filter the buffer
   36.42 +  // before it is flushed.
   36.43 +  virtual void flush();
   36.44 +
   36.45    // Overrides PtrQueue::should_enqueue_buffer(). See the method's
   36.46    // definition for more information.
   36.47    virtual bool should_enqueue_buffer();
   36.48  
   36.49 -  // Apply the closure to all elements, and reset the index to make the
   36.50 -  // buffer empty.
   36.51 -  void apply_closure(ObjectClosure* cl);
   36.52 -
   36.53 -  // Apply the closure to all elements of "buf", down to "index" (inclusive.)
   36.54 -  static void apply_closure_to_buffer(ObjectClosure* cl,
   36.55 -                                      void** buf, size_t index, size_t sz);
   36.56 +#ifndef PRODUCT
   36.57 +  // Helpful for debugging
   36.58 +  void print(const char* name);
   36.59 +  static void print(const char* name, void** buf, size_t index, size_t sz);
   36.60 +#endif // PRODUCT
   36.61  
   36.62    void verify_oops_in_buffer() NOT_DEBUG_RETURN;
   36.63  };
   36.64  
   36.65 -
   36.66 -
   36.67  class SATBMarkQueueSet: public PtrQueueSet {
   36.68    ObjectClosure* _closure;
   36.69    ObjectClosure** _par_closures;  // One per ParGCThread.
   36.70 @@ -88,6 +105,9 @@
   36.71    // set itself, has an active value same as expected_active.
   36.72    void set_active_all_threads(bool b, bool expected_active);
   36.73  
   36.74 +  // Filter all the currently-active SATB buffers.
   36.75 +  void filter_thread_buffers();
   36.76 +
   36.77    // Register "blk" as "the closure" for all queues.  Only one such closure
   36.78    // is allowed.  The "apply_closure_to_completed_buffer" method will apply
   36.79    // this closure to a completed buffer, and "iterate_closure_all_threads"
   36.80 @@ -98,10 +118,9 @@
   36.81    // closures, one for each parallel GC thread.
   36.82    void set_par_closure(int i, ObjectClosure* closure);
   36.83  
   36.84 -  // If there is a registered closure for buffers, apply it to all entries
   36.85 -  // in all currently-active buffers.  This should only be applied at a
   36.86 -  // safepoint.  (Currently must not be called in parallel; this should
   36.87 -  // change in the future.)
   36.88 +  // Apply the registered closure to all entries on each
   36.89 +  // currently-active buffer and then empty the buffer. It should only
   36.90 +  // be called serially and at a safepoint.
   36.91    void iterate_closure_all_threads();
   36.92    // Parallel version of the above.
   36.93    void par_iterate_closure_all_threads(int worker);
   36.94 @@ -117,11 +136,21 @@
   36.95      return apply_closure_to_completed_buffer_work(true, worker);
   36.96    }
   36.97  
   36.98 +  // Apply the given closure on enqueued and currently-active buffers
   36.99 +  // respectively. Both methods are read-only, i.e., they do not
  36.100 +  // modify any of the buffers.
  36.101 +  void iterate_completed_buffers_read_only(ObjectClosure* cl);
  36.102 +  void iterate_thread_buffers_read_only(ObjectClosure* cl);
  36.103 +
  36.104 +#ifndef PRODUCT
  36.105 +  // Helpful for debugging
  36.106 +  void print_all(const char* msg);
  36.107 +#endif // PRODUCT
  36.108 +
  36.109    ObjPtrQueue* shared_satb_queue() { return &_shared_satb_queue; }
  36.110  
  36.111    // If a marking is being abandoned, reset any unprocessed log buffers.
  36.112    void abandon_partial_marking();
  36.113 -
  36.114  };
  36.115  
  36.116  #endif // SHARE_VM_GC_IMPLEMENTATION_G1_SATBQUEUE_HPP
    37.1 --- a/src/share/vm/oops/instanceKlass.hpp	Sat Jan 21 23:02:40 2012 -0500
    37.2 +++ b/src/share/vm/oops/instanceKlass.hpp	Mon Jan 23 17:45:32 2012 -0800
    37.3 @@ -231,6 +231,10 @@
    37.4    u2              _java_fields_count;    // The number of declared Java fields
    37.5    int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
    37.6  
    37.7 +  bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
    37.8 +  bool            _rewritten;            // methods rewritten.
    37.9 +  bool            _has_nonstatic_fields; // for sizing with UseCompressedOops
   37.10 +  bool            _should_verify_class;  // allow caching of preverification
   37.11    u2              _minor_version;        // minor version number of class file
   37.12    u2              _major_version;        // major version number of class file
   37.13    Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recusive initialization)
   37.14 @@ -261,19 +265,6 @@
   37.15    // _idnum_allocated_count.
   37.16    u1              _init_state;                    // state of class
   37.17  
   37.18 -  // Compact the following four boolean flags into 1-bit each.  These four flags
   37.19 -  // were defined as separate boolean fields and each was 1-byte before. Since
   37.20 -  // there are 2 bytes unused after the _idnum_allocated_count field, place the
   37.21 -  // _misc_flags field after _idnum_allocated_count to utilize the unused bits
   37.22 -  // and save total 4-bytes.
   37.23 -  enum {
   37.24 -    IS_MARKED_DEPENDENT  = 0x1, // used for marking during flushing and deoptimization
   37.25 -    REWRITTEN            = 0x2, // methods rewritten.
   37.26 -    HAS_NONSTATIC_FIELDS = 0x4, // for sizing with UseCompressedOops
   37.27 -    SHOULD_VERIFY_CLASS  = 0x8  // allow caching of preverification
   37.28 -  };
   37.29 -  u1              _misc_flags;
   37.30 -
   37.31    // embedded Java vtable follows here
   37.32    // embedded Java itables follows here
   37.33    // embedded static fields follows here
   37.34 @@ -283,14 +274,8 @@
   37.35    friend class SystemDictionary;
   37.36  
   37.37   public:
   37.38 -  bool has_nonstatic_fields() const        { return (_misc_flags & HAS_NONSTATIC_FIELDS) != 0; }
   37.39 -  void set_has_nonstatic_fields(bool b) {
   37.40 -    if (b) {
   37.41 -      _misc_flags |= HAS_NONSTATIC_FIELDS;
   37.42 -    } else {
   37.43 -      _misc_flags &= ~HAS_NONSTATIC_FIELDS;
   37.44 -    }
   37.45 -  }
   37.46 +  bool has_nonstatic_fields() const        { return _has_nonstatic_fields; }
   37.47 +  void set_has_nonstatic_fields(bool b)    { _has_nonstatic_fields = b; }
   37.48  
   37.49    // field sizes
   37.50    int nonstatic_field_size() const         { return _nonstatic_field_size; }
   37.51 @@ -398,23 +383,15 @@
   37.52    bool is_in_error_state() const           { return _init_state == initialization_error; }
   37.53    bool is_reentrant_initialization(Thread *thread)  { return thread == _init_thread; }
   37.54    ClassState  init_state()                 { return (ClassState)_init_state; }
   37.55 -  bool is_rewritten() const                { return (_misc_flags & REWRITTEN) != 0; }
   37.56 +  bool is_rewritten() const                { return _rewritten; }
   37.57  
   37.58    // defineClass specified verification
   37.59 -  bool should_verify_class() const         { return (_misc_flags & SHOULD_VERIFY_CLASS) != 0; }
   37.60 -  void set_should_verify_class(bool value) {
   37.61 -    if (value) {
   37.62 -      _misc_flags |= SHOULD_VERIFY_CLASS;
   37.63 -    } else {
   37.64 -      _misc_flags &= ~SHOULD_VERIFY_CLASS;
   37.65 -    }
   37.66 -  }
   37.67 -
   37.68 +  bool should_verify_class() const         { return _should_verify_class; }
   37.69 +  void set_should_verify_class(bool value) { _should_verify_class = value; }
   37.70  
   37.71    // marking
   37.72 -  bool is_marked_dependent() const         { return (_misc_flags & IS_MARKED_DEPENDENT) != 0; }
   37.73 -  void set_is_marked_dependent()           { _misc_flags |= IS_MARKED_DEPENDENT; }
   37.74 -  void clear_is_marked_dependent()         { _misc_flags &= ~IS_MARKED_DEPENDENT; }
   37.75 +  bool is_marked_dependent() const         { return _is_marked_dependent; }
   37.76 +  void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
   37.77  
   37.78    // initialization (virtuals from Klass)
   37.79    bool should_be_initialized() const;  // means that initialize should be called
   37.80 @@ -784,7 +761,7 @@
   37.81  #else
   37.82    void set_init_state(ClassState state) { _init_state = (u1)state; }
   37.83  #endif
   37.84 -  void set_rewritten()                  { _misc_flags |= REWRITTEN; }
   37.85 +  void set_rewritten()                  { _rewritten = true; }
   37.86    void set_init_thread(Thread *thread)  { _init_thread = thread; }
   37.87  
   37.88    u2 idnum_allocated_count() const      { return _idnum_allocated_count; }
    38.1 --- a/src/share/vm/oops/instanceKlassKlass.cpp	Sat Jan 21 23:02:40 2012 -0500
    38.2 +++ b/src/share/vm/oops/instanceKlassKlass.cpp	Mon Jan 23 17:45:32 2012 -0800
    38.3 @@ -399,7 +399,7 @@
    38.4      ik->set_inner_classes(NULL);
    38.5      ik->set_static_oop_field_count(0);
    38.6      ik->set_nonstatic_field_size(0);
    38.7 -    ik->clear_is_marked_dependent();
    38.8 +    ik->set_is_marked_dependent(false);
    38.9      ik->set_init_state(instanceKlass::allocated);
   38.10      ik->set_init_thread(NULL);
   38.11      ik->set_reference_type(rt);
    39.1 --- a/src/share/vm/opto/c2_globals.hpp	Sat Jan 21 23:02:40 2012 -0500
    39.2 +++ b/src/share/vm/opto/c2_globals.hpp	Mon Jan 23 17:45:32 2012 -0800
    39.3 @@ -426,6 +426,9 @@
    39.4    product(bool, EliminateLocks, true,                                       \
    39.5            "Coarsen locks when possible")                                    \
    39.6                                                                              \
    39.7 +  product(bool, EliminateNestedLocks, true,                                 \
    39.8 +          "Eliminate nested locks of the same object when possible")        \
    39.9 +                                                                            \
   39.10    notproduct(bool, PrintLockStatistics, false,                              \
   39.11            "Print precise statistics on the dynamic lock usage")             \
   39.12                                                                              \
    40.1 --- a/src/share/vm/opto/callnode.cpp	Sat Jan 21 23:02:40 2012 -0500
    40.2 +++ b/src/share/vm/opto/callnode.cpp	Mon Jan 23 17:45:32 2012 -0800
    40.3 @@ -400,10 +400,10 @@
    40.4        Node *box = mcall->monitor_box(this, i);
    40.5        Node *obj = mcall->monitor_obj(this, i);
    40.6        if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
    40.7 -        while( !box->is_BoxLock() )  box = box->in(1);
    40.8 +        box = BoxLockNode::box_node(box);
    40.9          format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
   40.10        } else {
   40.11 -        OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
   40.12 +        OptoReg::Name box_reg = BoxLockNode::reg(box);
   40.13          st->print(" MON-BOX%d=%s+%d",
   40.14                     i,
   40.15                     OptoReg::regname(OptoReg::c_frame_pointer),
   40.16 @@ -411,8 +411,7 @@
   40.17        }
   40.18        const char* obj_msg = "MON-OBJ[";
   40.19        if (EliminateLocks) {
   40.20 -        while( !box->is_BoxLock() )  box = box->in(1);
   40.21 -        if (box->as_BoxLock()->is_eliminated())
   40.22 +        if (BoxLockNode::box_node(box)->is_eliminated())
   40.23            obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
   40.24        }
   40.25        format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
   40.26 @@ -1387,8 +1386,9 @@
   40.27      Node *n = ctrl_proj->in(0);
   40.28      if (n != NULL && n->is_Unlock()) {
   40.29        UnlockNode *unlock = n->as_Unlock();
   40.30 -      if ((lock->obj_node() == unlock->obj_node()) &&
   40.31 -          (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) {
   40.32 +      if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
   40.33 +          BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) &&
   40.34 +          !unlock->is_eliminated()) {
   40.35          lock_ops.append(unlock);
   40.36          return true;
   40.37        }
   40.38 @@ -1431,8 +1431,8 @@
   40.39    }
   40.40    if (ctrl->is_Lock()) {
   40.41      LockNode *lock = ctrl->as_Lock();
   40.42 -    if ((lock->obj_node() == unlock->obj_node()) &&
   40.43 -            (lock->box_node() == unlock->box_node())) {
   40.44 +    if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
   40.45 +        BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) {
   40.46        lock_result = lock;
   40.47      }
   40.48    }
   40.49 @@ -1462,8 +1462,9 @@
   40.50        }
   40.51        if (lock1_node != NULL && lock1_node->is_Lock()) {
   40.52          LockNode *lock1 = lock1_node->as_Lock();
   40.53 -        if ((lock->obj_node() == lock1->obj_node()) &&
   40.54 -            (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) {
   40.55 +        if (lock->obj_node()->eqv_uncast(lock1->obj_node()) &&
   40.56 +            BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) &&
   40.57 +            !lock1->is_eliminated()) {
   40.58            lock_ops.append(lock1);
   40.59            return true;
   40.60          }
   40.61 @@ -1507,19 +1508,16 @@
   40.62  void AbstractLockNode::create_lock_counter(JVMState* state) {
   40.63    _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
   40.64  }
   40.65 -#endif
   40.66  
   40.67 -void AbstractLockNode::set_eliminated() {
   40.68 -  _eliminate = true;
   40.69 -#ifndef PRODUCT
   40.70 +void AbstractLockNode::set_eliminated_lock_counter() {
   40.71    if (_counter) {
   40.72      // Update the counter to indicate that this lock was eliminated.
   40.73      // The counter update code will stay around even though the
   40.74      // optimizer will eliminate the lock operation itself.
   40.75      _counter->set_tag(NamedCounter::EliminatedLockCounter);
   40.76    }
   40.77 +}
   40.78  #endif
   40.79 -}
   40.80  
   40.81  //=============================================================================
   40.82  Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   40.83 @@ -1535,7 +1533,7 @@
   40.84    // prevents macro expansion from expanding the lock.  Since we don't
   40.85    // modify the graph, the value returned from this function is the
   40.86    // one computed above.
   40.87 -  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
   40.88 +  if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
   40.89      //
   40.90      // If we are locking an unescaped object, the lock/unlock is unnecessary
   40.91      //
   40.92 @@ -1544,16 +1542,11 @@
   40.93      if (cgr != NULL)
   40.94        es = cgr->escape_state(obj_node());
   40.95      if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
   40.96 -      if (!is_eliminated()) {
   40.97 -        // Mark it eliminated to update any counters
   40.98 -        this->set_eliminated();
   40.99 -      } else {
  40.100 -        assert(is_coarsened(), "sanity");
  40.101 -        // The lock could be marked eliminated by lock coarsening
  40.102 -        // code during first IGVN before EA. Clear coarsened flag
  40.103 -        // to eliminate all associated locks/unlocks.
  40.104 -        this->clear_coarsened();
  40.105 -      }
  40.106 +      assert(!is_eliminated() || is_coarsened(), "sanity");
  40.107 +      // The lock could be marked eliminated by lock coarsening
  40.108 +      // code during first IGVN before EA. Replace coarsened flag
  40.109 +      // to eliminate all associated locks/unlocks.
  40.110 +      this->set_non_esc_obj();
  40.111        return result;
  40.112      }
  40.113  
  40.114 @@ -1613,8 +1606,7 @@
  40.115          for (int i = 0; i < lock_ops.length(); i++) {
  40.116            AbstractLockNode* lock = lock_ops.at(i);
  40.117  
  40.118 -          // Mark it eliminated to update any counters
  40.119 -          lock->set_eliminated();
  40.120 +          // Mark it eliminated by coarsening and update any counters
  40.121            lock->set_coarsened();
  40.122          }
  40.123        } else if (ctrl->is_Region() &&
  40.124 @@ -1632,6 +1624,40 @@
  40.125  }
  40.126  
  40.127  //=============================================================================
  40.128 +bool LockNode::is_nested_lock_region() {
  40.129 +  BoxLockNode* box = box_node()->as_BoxLock();
  40.130 +  int stk_slot = box->stack_slot();
  40.131 +  if (stk_slot <= 0)
  40.132 +    return false; // External lock or it is not Box (Phi node).
  40.133 +
  40.134 +  // Ignore complex cases: merged locks or multiple locks.
  40.135 +  Node* obj = obj_node();
  40.136 +  LockNode* unique_lock = NULL;
  40.137 +  if (!box->is_simple_lock_region(&unique_lock, obj) ||
  40.138 +      (unique_lock != this)) {
  40.139 +    return false;
  40.140 +  }
  40.141 +
  40.142 +  // Look for external lock for the same object.
  40.143 +  SafePointNode* sfn = this->as_SafePoint();
  40.144 +  JVMState* youngest_jvms = sfn->jvms();
  40.145 +  int max_depth = youngest_jvms->depth();
  40.146 +  for (int depth = 1; depth <= max_depth; depth++) {
  40.147 +    JVMState* jvms = youngest_jvms->of_depth(depth);
  40.148 +    int num_mon  = jvms->nof_monitors();
  40.149 +    // Loop over monitors
  40.150 +    for (int idx = 0; idx < num_mon; idx++) {
  40.151 +      Node* obj_node = sfn->monitor_obj(jvms, idx);
  40.152 +      BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock();
  40.153 +      if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) {
  40.154 +        return true;
  40.155 +      }
  40.156 +    }
  40.157 +  }
  40.158 +  return false;
  40.159 +}
  40.160 +
  40.161 +//=============================================================================
  40.162  uint UnlockNode::size_of() const { return sizeof(*this); }
  40.163  
  40.164  //=============================================================================
  40.165 @@ -1649,7 +1675,7 @@
  40.166    // modify the graph, the value returned from this function is the
  40.167    // one computed above.
  40.168    // Escape state is defined after Parse phase.
  40.169 -  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
  40.170 +  if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
  40.171      //
  40.172      // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
  40.173      //
  40.174 @@ -1658,16 +1684,11 @@
  40.175      if (cgr != NULL)
  40.176        es = cgr->escape_state(obj_node());
  40.177      if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
  40.178 -      if (!is_eliminated()) {
  40.179 -        // Mark it eliminated to update any counters
  40.180 -        this->set_eliminated();
  40.181 -      } else {
  40.182 -        assert(is_coarsened(), "sanity");
  40.183 -        // The lock could be marked eliminated by lock coarsening
  40.184 -        // code during first IGVN before EA. Clear coarsened flag
  40.185 -        // to eliminate all associated locks/unlocks.
  40.186 -        this->clear_coarsened();
  40.187 -      }
  40.188 +      assert(!is_eliminated() || is_coarsened(), "sanity");
  40.189 +      // The lock could be marked eliminated by lock coarsening
  40.190 +      // code during first IGVN before EA. Replace coarsened flag
  40.191 +      // to eliminate all associated locks/unlocks.
  40.192 +      this->set_non_esc_obj();
  40.193      }
  40.194    }
  40.195    return result;
    41.1 --- a/src/share/vm/opto/callnode.hpp	Sat Jan 21 23:02:40 2012 -0500
    41.2 +++ b/src/share/vm/opto/callnode.hpp	Mon Jan 23 17:45:32 2012 -0800
    41.3 @@ -840,8 +840,12 @@
    41.4  //------------------------------AbstractLockNode-----------------------------------
    41.5  class AbstractLockNode: public CallNode {
    41.6  private:
    41.7 -  bool _eliminate;    // indicates this lock can be safely eliminated
    41.8 -  bool _coarsened;    // indicates this lock was coarsened
    41.9 +  enum {
   41.10 +    Regular = 0,  // Normal lock
   41.11 +    NonEscObj,    // Lock is used for non escaping object
   41.12 +    Coarsened,    // Lock was coarsened
   41.13 +    Nested        // Nested lock
   41.14 +  } _kind;
   41.15  #ifndef PRODUCT
   41.16    NamedCounter* _counter;
   41.17  #endif
   41.18 @@ -858,12 +862,13 @@
   41.19                                 GrowableArray<AbstractLockNode*> &lock_ops);
   41.20    LockNode *find_matching_lock(UnlockNode* unlock);
   41.21  
   41.22 +  // Update the counter to indicate that this lock was eliminated.
   41.23 +  void set_eliminated_lock_counter() PRODUCT_RETURN;
   41.24  
   41.25  public:
   41.26    AbstractLockNode(const TypeFunc *tf)
   41.27      : CallNode(tf, NULL, TypeRawPtr::BOTTOM),
   41.28 -      _coarsened(false),
   41.29 -      _eliminate(false)
   41.30 +      _kind(Regular)
   41.31    {
   41.32  #ifndef PRODUCT
   41.33      _counter = NULL;
   41.34 @@ -873,20 +878,23 @@
   41.35    Node *   obj_node() const       {return in(TypeFunc::Parms + 0); }
   41.36    Node *   box_node() const       {return in(TypeFunc::Parms + 1); }
   41.37    Node *   fastlock_node() const  {return in(TypeFunc::Parms + 2); }
   41.38 +  void     set_box_node(Node* box) { set_req(TypeFunc::Parms + 1, box); }
   41.39 +
   41.40    const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;}
   41.41  
   41.42    virtual uint size_of() const { return sizeof(*this); }
   41.43  
   41.44 -  bool is_eliminated()         {return _eliminate; }
   41.45 -  // mark node as eliminated and update the counter if there is one
   41.46 -  void set_eliminated();
   41.47 +  bool is_eliminated()  const { return (_kind != Regular); }
   41.48 +  bool is_non_esc_obj() const { return (_kind == NonEscObj); }
   41.49 +  bool is_coarsened()   const { return (_kind == Coarsened); }
   41.50 +  bool is_nested()      const { return (_kind == Nested); }
   41.51  
   41.52 -  bool is_coarsened()  { return _coarsened; }
   41.53 -  void set_coarsened() { _coarsened = true; }
   41.54 -  void clear_coarsened() { _coarsened = false; }
   41.55 +  void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
   41.56 +  void set_coarsened()   { _kind = Coarsened; set_eliminated_lock_counter(); }
   41.57 +  void set_nested()      { _kind = Nested; set_eliminated_lock_counter(); }
   41.58  
   41.59    // locking does not modify its arguments
   41.60 -  virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
   41.61 +  virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
   41.62  
   41.63  #ifndef PRODUCT
   41.64    void create_lock_counter(JVMState* s);
   41.65 @@ -936,6 +944,8 @@
   41.66    virtual void  clone_jvms() {
   41.67      set_jvms(jvms()->clone_deep(Compile::current()));
   41.68    }
   41.69 +
   41.70 +  bool is_nested_lock_region(); // Is this Lock nested?
   41.71  };
   41.72  
   41.73  //------------------------------Unlock---------------------------------------
    42.1 --- a/src/share/vm/opto/cfgnode.cpp	Sat Jan 21 23:02:40 2012 -0500
    42.2 +++ b/src/share/vm/opto/cfgnode.cpp	Mon Jan 23 17:45:32 2012 -0800
    42.3 @@ -1597,7 +1597,7 @@
    42.4        bool is_loop = (r->is_Loop() && r->req() == 3);
    42.5        // Then, check if there is a data loop when phi references itself directly
    42.6        // or through other data nodes.
    42.7 -      if (is_loop && !phase->eqv_uncast(uin, in(LoopNode::EntryControl)) ||
    42.8 +      if (is_loop && !uin->eqv_uncast(in(LoopNode::EntryControl)) ||
    42.9           !is_loop && is_unsafe_data_reference(uin)) {
   42.10          // Break this data loop to avoid creation of a dead loop.
   42.11          if (can_reshape) {
    43.1 --- a/src/share/vm/opto/chaitin.hpp	Sat Jan 21 23:02:40 2012 -0500
    43.2 +++ b/src/share/vm/opto/chaitin.hpp	Mon Jan 23 17:45:32 2012 -0800
    43.3 @@ -485,7 +485,11 @@
    43.4      return yank_if_dead(old, current_block, &value, &regnd);
    43.5    }
    43.6  
    43.7 -  int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
    43.8 +  int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
    43.9 +    return yank_if_dead_recurse(old, old, current_block, value, regnd);
   43.10 +  }
   43.11 +  int yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block,
   43.12 +                           Node_List *value, Node_List *regnd);
   43.13    int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
   43.14    int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs );
   43.15    int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd );
    44.1 --- a/src/share/vm/opto/escape.cpp	Sat Jan 21 23:02:40 2012 -0500
    44.2 +++ b/src/share/vm/opto/escape.cpp	Mon Jan 23 17:45:32 2012 -0800
    44.3 @@ -1842,20 +1842,15 @@
    44.4        Node *n = C->macro_node(i);
    44.5        if (n->is_AbstractLock()) { // Lock and Unlock nodes
    44.6          AbstractLockNode* alock = n->as_AbstractLock();
    44.7 -        if (!alock->is_eliminated() || alock->is_coarsened()) {
    44.8 +        if (!alock->is_non_esc_obj()) {
    44.9            PointsToNode::EscapeState es = escape_state(alock->obj_node());
   44.10            assert(es != PointsToNode::UnknownEscape, "should know");
   44.11            if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
   44.12 -            if (!alock->is_eliminated()) {
   44.13 -              // Mark it eliminated to update any counters
   44.14 -              alock->set_eliminated();
   44.15 -            } else {
   44.16 -              // The lock could be marked eliminated by lock coarsening
   44.17 -              // code during first IGVN before EA. Clear coarsened flag
   44.18 -              // to eliminate all associated locks/unlocks and relock
   44.19 -              // during deoptimization.
   44.20 -              alock->clear_coarsened();
   44.21 -            }
   44.22 +            assert(!alock->is_eliminated() || alock->is_coarsened(), "sanity");
   44.23 +            // The lock could be marked eliminated by lock coarsening
   44.24 +            // code during first IGVN before EA. Replace coarsened flag
   44.25 +            // to eliminate all associated locks/unlocks.
   44.26 +            alock->set_non_esc_obj();
   44.27            }
   44.28          }
   44.29        }
    45.1 --- a/src/share/vm/opto/library_call.cpp	Sat Jan 21 23:02:40 2012 -0500
    45.2 +++ b/src/share/vm/opto/library_call.cpp	Mon Jan 23 17:45:32 2012 -0800
    45.3 @@ -819,7 +819,7 @@
    45.4    if (stopped())
    45.5      return NULL;                // already stopped
    45.6    bool zero_offset = _gvn.type(offset) == TypeInt::ZERO;
    45.7 -  if (zero_offset && _gvn.eqv_uncast(subseq_length, array_length))
    45.8 +  if (zero_offset && subseq_length->eqv_uncast(array_length))
    45.9      return NULL;                // common case of whole-array copy
   45.10    Node* last = subseq_length;
   45.11    if (!zero_offset)             // last += offset
   45.12 @@ -4667,7 +4667,7 @@
   45.13    if (ReduceBulkZeroing
   45.14        && !ZeroTLAB              // pointless if already zeroed
   45.15        && basic_elem_type != T_CONFLICT // avoid corner case
   45.16 -      && !_gvn.eqv_uncast(src, dest)
   45.17 +      && !src->eqv_uncast(dest)
   45.18        && ((alloc = tightly_coupled_allocation(dest, slow_region))
   45.19            != NULL)
   45.20        && _gvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0
   45.21 @@ -4745,7 +4745,7 @@
   45.22      // copy_length is 0.
   45.23      if (!stopped() && dest_uninitialized) {
   45.24        Node* dest_length = alloc->in(AllocateNode::ALength);
   45.25 -      if (_gvn.eqv_uncast(copy_length, dest_length)
   45.26 +      if (copy_length->eqv_uncast(dest_length)
   45.27            || _gvn.find_int_con(dest_length, 1) <= 0) {
   45.28          // There is no zeroing to do. No need for a secondary raw memory barrier.
   45.29        } else {
   45.30 @@ -4791,7 +4791,7 @@
   45.31      // with its attendant messy index arithmetic, and upgrade
   45.32      // the copy to a more hardware-friendly word size of 64 bits.
   45.33      Node* tail_ctl = NULL;
   45.34 -    if (!stopped() && !_gvn.eqv_uncast(dest_tail, dest_length)) {
   45.35 +    if (!stopped() && !dest_tail->eqv_uncast(dest_length)) {
   45.36        Node* cmp_lt   = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) );
   45.37        Node* bol_lt   = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) );
   45.38        tail_ctl = generate_slow_guard(bol_lt, NULL);
    46.1 --- a/src/share/vm/opto/locknode.cpp	Sat Jan 21 23:02:40 2012 -0500
    46.2 +++ b/src/share/vm/opto/locknode.cpp	Mon Jan 23 17:45:32 2012 -0800
    46.3 @@ -49,18 +49,22 @@
    46.4  
    46.5  //-----------------------------hash--------------------------------------------
    46.6  uint BoxLockNode::hash() const {
    46.7 +  if (EliminateNestedLocks)
    46.8 +    return NO_HASH; // Each locked region has own BoxLock node
    46.9    return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
   46.10  }
   46.11  
   46.12  //------------------------------cmp--------------------------------------------
   46.13  uint BoxLockNode::cmp( const Node &n ) const {
   46.14 +  if (EliminateNestedLocks)
   46.15 +    return (&n == this); // Always fail except on self
   46.16    const BoxLockNode &bn = (const BoxLockNode &)n;
   46.17    return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
   46.18  }
   46.19  
   46.20 -OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
   46.21 -  // Chase down the BoxNode
   46.22 -  while (!box_node->is_BoxLock()) {
   46.23 +BoxLockNode* BoxLockNode::box_node(Node* box) {
   46.24 +  // Chase down the BoxNode after RA which may spill box nodes.
   46.25 +  while (!box->is_BoxLock()) {
   46.26      //    if (box_node->is_SpillCopy()) {
   46.27      //      Node *m = box_node->in(1);
   46.28      //      if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_StoreP) {
   46.29 @@ -68,10 +72,64 @@
   46.30      //        continue;
   46.31      //      }
   46.32      //    }
   46.33 -    assert(box_node->is_SpillCopy() || box_node->is_Phi(), "Bad spill of Lock.");
   46.34 -    box_node = box_node->in(1);
   46.35 +    assert(box->is_SpillCopy() || box->is_Phi(), "Bad spill of Lock.");
   46.36 +    // Only BoxLock nodes with the same stack slot are merged.
   46.37 +    // So it is enough to trace one path to find the slot value.
   46.38 +    box = box->in(1);
   46.39    }
   46.40 -  return box_node->in_RegMask(0).find_first_elem();
   46.41 +  return box->as_BoxLock();
   46.42 +}
   46.43 +
   46.44 +OptoReg::Name BoxLockNode::reg(Node* box) {
   46.45 +  return box_node(box)->in_RegMask(0).find_first_elem();
   46.46 +}
   46.47 +
   46.48 +// Is BoxLock node used for one simple lock region (same box and obj)?
   46.49 +bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj) {
   46.50 +  LockNode* lock = NULL;
   46.51 +  bool has_one_lock = false;
   46.52 +  for (uint i = 0; i < this->outcnt(); i++) {
   46.53 +    Node* n = this->raw_out(i);
   46.54 +    assert(!n->is_Phi(), "should not merge BoxLock nodes");
   46.55 +    if (n->is_AbstractLock()) {
   46.56 +      AbstractLockNode* alock = n->as_AbstractLock();
   46.57 +      // Check lock's box since box could be referenced by Lock's debug info.
   46.58 +      if (alock->box_node() == this) {
   46.59 +        if (alock->obj_node()->eqv_uncast(obj)) {
   46.60 +          if ((unique_lock != NULL) && alock->is_Lock()) {
   46.61 +            if (lock == NULL) {
   46.62 +              lock = alock->as_Lock();
   46.63 +              has_one_lock = true;
   46.64 +            } else if (lock != alock->as_Lock()) {
   46.65 +              has_one_lock = false;
   46.66 +            }
   46.67 +          }
   46.68 +        } else {
   46.69 +          return false; // Different objects
   46.70 +        }
   46.71 +      }
   46.72 +    }
   46.73 +  }
   46.74 +#ifdef ASSERT
   46.75 +  // Verify that FastLock and Safepoint reference only this lock region.
   46.76 +  for (uint i = 0; i < this->outcnt(); i++) {
   46.77 +    Node* n = this->raw_out(i);
   46.78 +    if (n->is_FastLock()) {
   46.79 +      FastLockNode* flock = n->as_FastLock();
   46.80 +      assert((flock->box_node() == this) && flock->obj_node()->eqv_uncast(obj),"");
   46.81 +    }
   46.82 +    // Don't check monitor info in safepoints since the referenced object could
   46.83 +    // be different from the locked object. It could be Phi node of different
   46.84 +    // cast nodes which point to this locked object.
   46.85 +    // We assume that no other objects could be referenced in monitor info
   46.86 +    // associated with this BoxLock node because all associated locks and
   46.87 +    // unlocks are reference only this one object.
   46.88 +  }
   46.89 +#endif
   46.90 +  if (unique_lock != NULL && has_one_lock) {
   46.91 +    *unique_lock = lock;
   46.92 +  }
   46.93 +  return true;
   46.94  }
   46.95  
   46.96  //=============================================================================
    47.1 --- a/src/share/vm/opto/locknode.hpp	Sat Jan 21 23:02:40 2012 -0500
    47.2 +++ b/src/share/vm/opto/locknode.hpp	Mon Jan 23 17:45:32 2012 -0800
    47.3 @@ -49,11 +49,11 @@
    47.4  
    47.5  //------------------------------BoxLockNode------------------------------------
    47.6  class BoxLockNode : public Node {
    47.7 +  const int     _slot; // stack slot
    47.8 +  RegMask     _inmask; // OptoReg corresponding to stack slot
    47.9 +  bool _is_eliminated; // Associated locks were safely eliminated
   47.10 +
   47.11  public:
   47.12 -  const int _slot;
   47.13 -  RegMask   _inmask;
   47.14 -  bool _is_eliminated;    // indicates this lock was safely eliminated
   47.15 -
   47.16    BoxLockNode( int lock );
   47.17    virtual int Opcode() const;
   47.18    virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
   47.19 @@ -66,11 +66,19 @@
   47.20    virtual const class Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
   47.21    virtual uint ideal_reg() const { return Op_RegP; }
   47.22  
   47.23 -  static OptoReg::Name stack_slot(Node* box_node);
   47.24 +  static OptoReg::Name reg(Node* box_node);
   47.25 +  static BoxLockNode* box_node(Node* box_node);
   47.26 +  static bool same_slot(Node* box1, Node* box2) {
   47.27 +    return box1->as_BoxLock()->_slot == box2->as_BoxLock()->_slot;
   47.28 +  }
   47.29 +  int stack_slot() const { return _slot; }
   47.30  
   47.31 -  bool is_eliminated()  { return _is_eliminated; }
   47.32 +  bool is_eliminated() const { return _is_eliminated; }
   47.33    // mark lock as eliminated.
   47.34 -  void set_eliminated() { _is_eliminated = true; }
   47.35 +  void set_eliminated()      { _is_eliminated = true; }
   47.36 +
   47.37 +  // Is BoxLock node used for one simple lock region?
   47.38 +  bool is_simple_lock_region(LockNode** unique_lock, Node* obj);
   47.39  
   47.40  #ifndef PRODUCT
   47.41    virtual void format( PhaseRegAlloc *, outputStream *st ) const;
   47.42 @@ -91,6 +99,7 @@
   47.43    }
   47.44    Node* obj_node() const { return in(1); }
   47.45    Node* box_node() const { return in(2); }
   47.46 +  void  set_box_node(Node* box) { set_req(2, box); }
   47.47  
   47.48    // FastLock and FastUnlockNode do not hash, we need one for each correspoding
   47.49    // LockNode/UnLockNode to avoid creating Phi's.
    48.1 --- a/src/share/vm/opto/loopnode.cpp	Sat Jan 21 23:02:40 2012 -0500
    48.2 +++ b/src/share/vm/opto/loopnode.cpp	Mon Jan 23 17:45:32 2012 -0800
    48.3 @@ -3278,16 +3278,7 @@
    48.4  #ifdef ASSERT
    48.5      if (legal->is_Start() && !early->is_Root()) {
    48.6        // Bad graph. Print idom path and fail.
    48.7 -      tty->print_cr( "Bad graph detected in build_loop_late");
    48.8 -      tty->print("n: ");n->dump(); tty->cr();
    48.9 -      tty->print("early: ");early->dump(); tty->cr();
   48.10 -      int ct = 0;
   48.11 -      Node *dbg_legal = LCA;
   48.12 -      while(!dbg_legal->is_Start() && ct < 100) {
   48.13 -        tty->print("idom[%d] ",ct); dbg_legal->dump(); tty->cr();
   48.14 -        ct++;
   48.15 -        dbg_legal = idom(dbg_legal);
   48.16 -      }
   48.17 +      dump_bad_graph(n, early, LCA);
   48.18        assert(false, "Bad graph detected in build_loop_late");
   48.19      }
   48.20  #endif
   48.21 @@ -3337,6 +3328,88 @@
   48.22      chosen_loop->_body.push(n);// Collect inner loops
   48.23  }
   48.24  
   48.25 +#ifdef ASSERT
   48.26 +void PhaseIdealLoop::dump_bad_graph(Node* n, Node* early, Node* LCA) {
   48.27 +  tty->print_cr( "Bad graph detected in build_loop_late");
   48.28 +  tty->print("n: "); n->dump();
   48.29 +  tty->print("early(n): "); early->dump();
   48.30 +  if (n->in(0) != NULL  && !n->in(0)->is_top() &&
   48.31 +      n->in(0) != early && !n->in(0)->is_Root()) {
   48.32 +    tty->print("n->in(0): "); n->in(0)->dump();
   48.33 +  }
   48.34 +  for (uint i = 1; i < n->req(); i++) {
   48.35 +    Node* in1 = n->in(i);
   48.36 +    if (in1 != NULL && in1 != n && !in1->is_top()) {
   48.37 +      tty->print("n->in(%d): ", i); in1->dump();
   48.38 +      Node* in1_early = get_ctrl(in1);
   48.39 +      tty->print("early(n->in(%d)): ", i); in1_early->dump();
   48.40 +      if (in1->in(0) != NULL     && !in1->in(0)->is_top() &&
   48.41 +          in1->in(0) != in1_early && !in1->in(0)->is_Root()) {
   48.42 +        tty->print("n->in(%d)->in(0): ", i); in1->in(0)->dump();
   48.43 +      }
   48.44 +      for (uint j = 1; j < in1->req(); j++) {
   48.45 +        Node* in2 = in1->in(j);
   48.46 +        if (in2 != NULL && in2 != n && in2 != in1 && !in2->is_top()) {
   48.47 +          tty->print("n->in(%d)->in(%d): ", i, j); in2->dump();
   48.48 +          Node* in2_early = get_ctrl(in2);
   48.49 +          tty->print("early(n->in(%d)->in(%d)): ", i, j); in2_early->dump();
   48.50 +          if (in2->in(0) != NULL     && !in2->in(0)->is_top() &&
   48.51 +              in2->in(0) != in2_early && !in2->in(0)->is_Root()) {
   48.52 +            tty->print("n->in(%d)->in(%d)->in(0): ", i, j); in2->in(0)->dump();
   48.53 +          }
   48.54 +        }
   48.55 +      }
   48.56 +    }
   48.57 +  }
   48.58 +  tty->cr();
   48.59 +  tty->print("LCA(n): "); LCA->dump();
   48.60 +  for (uint i = 0; i < n->outcnt(); i++) {
   48.61 +    Node* u1 = n->raw_out(i);
   48.62 +    if (u1 == n)
   48.63 +      continue;
   48.64 +    tty->print("n->out(%d): ", i); u1->dump();
   48.65 +    if (u1->is_CFG()) {
   48.66 +      for (uint j = 0; j < u1->outcnt(); j++) {
   48.67 +        Node* u2 = u1->raw_out(j);
   48.68 +        if (u2 != u1 && u2 != n && u2->is_CFG()) {
   48.69 +          tty->print("n->out(%d)->out(%d): ", i, j); u2->dump();
   48.70 +        }
   48.71 +      }
   48.72 +    } else {
   48.73 +      Node* u1_later = get_ctrl(u1);
   48.74 +      tty->print("later(n->out(%d)): ", i); u1_later->dump();
   48.75 +      if (u1->in(0) != NULL     && !u1->in(0)->is_top() &&
   48.76 +          u1->in(0) != u1_later && !u1->in(0)->is_Root()) {
   48.77 +        tty->print("n->out(%d)->in(0): ", i); u1->in(0)->dump();
   48.78 +      }
   48.79 +      for (uint j = 0; j < u1->outcnt(); j++) {
   48.80 +        Node* u2 = u1->raw_out(j);
   48.81 +        if (u2 == n || u2 == u1)
   48.82 +          continue;
   48.83 +        tty->print("n->out(%d)->out(%d): ", i, j); u2->dump();
   48.84 +        if (!u2->is_CFG()) {
   48.85 +          Node* u2_later = get_ctrl(u2);
   48.86 +          tty->print("later(n->out(%d)->out(%d)): ", i, j); u2_later->dump();
   48.87 +          if (u2->in(0) != NULL     && !u2->in(0)->is_top() &&
   48.88 +              u2->in(0) != u2_later && !u2->in(0)->is_Root()) {
   48.89 +            tty->print("n->out(%d)->in(0): ", i); u2->in(0)->dump();
   48.90 +          }
   48.91 +        }
   48.92 +      }
   48.93 +    }
   48.94 +  }
   48.95 +  tty->cr();
   48.96 +  int ct = 0;
   48.97 +  Node *dbg_legal = LCA;
   48.98 +  while(!dbg_legal->is_Start() && ct < 100) {
   48.99 +    tty->print("idom[%d] ",ct); dbg_legal->dump();
  48.100 +    ct++;
  48.101 +    dbg_legal = idom(dbg_legal);
  48.102 +  }
  48.103 +  tty->cr();
  48.104 +}
  48.105 +#endif
  48.106 +
  48.107  #ifndef PRODUCT
  48.108  //------------------------------dump-------------------------------------------
  48.109  void PhaseIdealLoop::dump( ) const {
    49.1 --- a/src/share/vm/opto/loopnode.hpp	Sat Jan 21 23:02:40 2012 -0500
    49.2 +++ b/src/share/vm/opto/loopnode.hpp	Mon Jan 23 17:45:32 2012 -0800
    49.3 @@ -1040,6 +1040,10 @@
    49.4    bool created_loop_node()     { return _created_loop_node; }
    49.5    void register_new_node( Node *n, Node *blk );
    49.6  
    49.7 +#ifdef ASSERT
    49.8 +void dump_bad_graph(Node* n, Node* early, Node* LCA);
    49.9 +#endif
   49.10 +
   49.11  #ifndef PRODUCT
   49.12    void dump( ) const;
   49.13    void dump( IdealLoopTree *loop, uint rpo_idx, Node_List &rpo_list ) const;
    50.1 --- a/src/share/vm/opto/loopopts.cpp	Sat Jan 21 23:02:40 2012 -0500
    50.2 +++ b/src/share/vm/opto/loopopts.cpp	Mon Jan 23 17:45:32 2012 -0800
    50.3 @@ -819,6 +819,8 @@
    50.4      if( iff->is_If() ) {        // Classic split-if?
    50.5        if( iff->in(0) != n_ctrl ) return; // Compare must be in same blk as if
    50.6      } else if (iff->is_CMove()) { // Trying to split-up a CMOVE
    50.7 +      // Can't split CMove with different control edge.
    50.8 +      if (iff->in(0) != NULL && iff->in(0) != n_ctrl ) return;
    50.9        if( get_ctrl(iff->in(2)) == n_ctrl ||
   50.10            get_ctrl(iff->in(3)) == n_ctrl )
   50.11          return;                 // Inputs not yet split-up
   50.12 @@ -937,7 +939,7 @@
   50.13        }
   50.14        bool did_break = (i < imax);  // Did we break out of the previous loop?
   50.15        if (!did_break && n->outcnt() > 1) { // All uses in outer loops!
   50.16 -        Node *late_load_ctrl;
   50.17 +        Node *late_load_ctrl = NULL;
   50.18          if (n->is_Load()) {
   50.19            // If n is a load, get and save the result from get_late_ctrl(),
   50.20            // to be later used in calculating the control for n's clones.
    51.1 --- a/src/share/vm/opto/macro.cpp	Sat Jan 21 23:02:40 2012 -0500
    51.2 +++ b/src/share/vm/opto/macro.cpp	Mon Jan 23 17:45:32 2012 -0800
    51.3 @@ -1789,7 +1789,8 @@
    51.4                           slow_call_address);
    51.5  }
    51.6  
    51.7 -//-----------------------mark_eliminated_locking_nodes-----------------------
    51.8 +//-------------------mark_eliminated_box----------------------------------
    51.9 +//
   51.10  // During EA obj may point to several objects but after few ideal graph
   51.11  // transformations (CCP) it may point to only one non escaping object
   51.12  // (but still using phi), corresponding locks and unlocks will be marked
   51.13 @@ -1800,62 +1801,148 @@
   51.14  // marked for elimination since new obj has no escape information.
   51.15  // Mark all associated (same box and obj) lock and unlock nodes for
   51.16  // elimination if some of them marked already.
   51.17 -void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
   51.18 -  if (!alock->is_eliminated()) {
   51.19 +void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) {
   51.20 +  if (oldbox->as_BoxLock()->is_eliminated())
   51.21 +    return; // This BoxLock node was processed already.
   51.22 +
   51.23 +  // New implementation (EliminateNestedLocks) has separate BoxLock
   51.24 +  // node for each locked region so mark all associated locks/unlocks as
   51.25 +  // eliminated even if different objects are referenced in one locked region
   51.26 +  // (for example, OSR compilation of nested loop inside locked scope).
   51.27 +  if (EliminateNestedLocks ||
   51.28 +      oldbox->as_BoxLock()->is_simple_lock_region(NULL, obj)) {
   51.29 +    // Box is used only in one lock region. Mark this box as eliminated.
   51.30 +    _igvn.hash_delete(oldbox);
   51.31 +    oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value
   51.32 +    _igvn.hash_insert(oldbox);
   51.33 +
   51.34 +    for (uint i = 0; i < oldbox->outcnt(); i++) {
   51.35 +      Node* u = oldbox->raw_out(i);
   51.36 +      if (u->is_AbstractLock() && !u->as_AbstractLock()->is_non_esc_obj()) {
   51.37 +        AbstractLockNode* alock = u->as_AbstractLock();
   51.38 +        // Check lock's box since box could be referenced by Lock's debug info.
   51.39 +        if (alock->box_node() == oldbox) {
   51.40 +          // Mark eliminated all related locks and unlocks.
   51.41 +          alock->set_non_esc_obj();
   51.42 +        }
   51.43 +      }
   51.44 +    }
   51.45      return;
   51.46    }
   51.47 -  if (!alock->is_coarsened()) { // Eliminated by EA
   51.48 -      // Create new "eliminated" BoxLock node and use it
   51.49 -      // in monitor debug info for the same object.
   51.50 -      BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
   51.51 -      Node* obj = alock->obj_node();
   51.52 -      if (!oldbox->is_eliminated()) {
   51.53 -        BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
   51.54 +
   51.55 +  // Create new "eliminated" BoxLock node and use it in monitor debug info
   51.56 +  // instead of oldbox for the same object.
   51.57 +  BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
   51.58 +
   51.59 +  // Note: BoxLock node is marked eliminated only here and it is used
   51.60 +  // to indicate that all associated lock and unlock nodes are marked
   51.61 +  // for elimination.
   51.62 +  newbox->set_eliminated();
   51.63 +  transform_later(newbox);
   51.64 +
   51.65 +  // Replace old box node with new box for all users of the same object.
   51.66 +  for (uint i = 0; i < oldbox->outcnt();) {
   51.67 +    bool next_edge = true;
   51.68 +
   51.69 +    Node* u = oldbox->raw_out(i);
   51.70 +    if (u->is_AbstractLock()) {
   51.71 +      AbstractLockNode* alock = u->as_AbstractLock();
   51.72 +      if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) {
   51.73 +        // Replace Box and mark eliminated all related locks and unlocks.
   51.74 +        alock->set_non_esc_obj();
   51.75 +        _igvn.hash_delete(alock);
   51.76 +        alock->set_box_node(newbox);
   51.77 +        _igvn._worklist.push(alock);
   51.78 +        next_edge = false;
   51.79 +      }
   51.80 +    }
   51.81 +    if (u->is_FastLock() && u->as_FastLock()->obj_node()->eqv_uncast(obj)) {
   51.82 +      FastLockNode* flock = u->as_FastLock();
   51.83 +      assert(flock->box_node() == oldbox, "sanity");
   51.84 +      _igvn.hash_delete(flock);
   51.85 +      flock->set_box_node(newbox);
   51.86 +      _igvn._worklist.push(flock);
   51.87 +      next_edge = false;
   51.88 +    }
   51.89 +
   51.90 +    // Replace old box in monitor debug info.
   51.91 +    if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
   51.92 +      SafePointNode* sfn = u->as_SafePoint();
   51.93 +      JVMState* youngest_jvms = sfn->jvms();
   51.94 +      int max_depth = youngest_jvms->depth();
   51.95 +      for (int depth = 1; depth <= max_depth; depth++) {
   51.96 +        JVMState* jvms = youngest_jvms->of_depth(depth);
   51.97 +        int num_mon  = jvms->nof_monitors();
   51.98 +        // Loop over monitors
   51.99 +        for (int idx = 0; idx < num_mon; idx++) {
  51.100 +          Node* obj_node = sfn->monitor_obj(jvms, idx);
  51.101 +          Node* box_node = sfn->monitor_box(jvms, idx);
  51.102 +          if (box_node == oldbox && obj_node->eqv_uncast(obj)) {
  51.103 +            int j = jvms->monitor_box_offset(idx);
  51.104 +            _igvn.hash_delete(u);
  51.105 +            u->set_req(j, newbox);
  51.106 +            _igvn._worklist.push(u);
  51.107 +            next_edge = false;
  51.108 +          }
  51.109 +        }
  51.110 +      }
  51.111 +    }
  51.112 +    if (next_edge) i++;
  51.113 +  }
  51.114 +}
  51.115 +
  51.116 +//-----------------------mark_eliminated_locking_nodes-----------------------
  51.117 +void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
  51.118 +  if (EliminateNestedLocks) {
  51.119 +    if (alock->is_nested()) {
  51.120 +       assert(alock->box_node()->as_BoxLock()->is_eliminated(), "sanity");
  51.121 +       return;
  51.122 +    } else if (!alock->is_non_esc_obj()) { // Not eliminated or coarsened
  51.123 +      // Only Lock node has JVMState needed here.
  51.124 +      if (alock->jvms() != NULL && alock->as_Lock()->is_nested_lock_region()) {
  51.125 +        // Mark eliminated related nested locks and unlocks.
  51.126 +        Node* obj = alock->obj_node();
  51.127 +        BoxLockNode* box_node = alock->box_node()->as_BoxLock();
  51.128 +        assert(!box_node->is_eliminated(), "should not be marked yet");
  51.129          // Note: BoxLock node is marked eliminated only here
  51.130          // and it is used to indicate that all associated lock
  51.131          // and unlock nodes are marked for elimination.
  51.132 -        newbox->set_eliminated();
  51.133 -        transform_later(newbox);
  51.134 -        // Replace old box node with new box for all users
  51.135 -        // of the same object.
  51.136 -        for (uint i = 0; i < oldbox->outcnt();) {
  51.137 +        box_node->set_eliminated(); // Box's hash is always NO_HASH here
  51.138 +        for (uint i = 0; i < box_node->outcnt(); i++) {
  51.139 +          Node* u = box_node->raw_out(i);
  51.140 +          if (u->is_AbstractLock()) {
  51.141 +            alock = u->as_AbstractLock();
  51.142 +            if (alock->box_node() == box_node) {
  51.143 +              // Verify that this Box is referenced only by related locks.
  51.144 +              assert(alock->obj_node()->eqv_uncast(obj), "");
  51.145 +              // Mark all related locks and unlocks.
  51.146 +              alock->set_nested();
  51.147 +            }
  51.148 +          }
  51.149 +        }
  51.150 +      }
  51.151 +      return;
  51.152 +    }
  51.153 +    // Process locks for non escaping object
  51.154 +    assert(alock->is_non_esc_obj(), "");
  51.155 +  } // EliminateNestedLocks
  51.156  
  51.157 -          bool next_edge = true;
  51.158 -          Node* u = oldbox->raw_out(i);
  51.159 -          if (u->is_AbstractLock() &&
  51.160 -              u->as_AbstractLock()->obj_node() == obj &&
  51.161 -              u->as_AbstractLock()->box_node() == oldbox) {
  51.162 -            // Mark all associated locks and unlocks.
  51.163 -            u->as_AbstractLock()->set_eliminated();
  51.164 -            _igvn.hash_delete(u);
  51.165 -            u->set_req(TypeFunc::Parms + 1, newbox);
  51.166 -            next_edge = false;
  51.167 -          }
  51.168 -          // Replace old box in monitor debug info.
  51.169 -          if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
  51.170 -            SafePointNode* sfn = u->as_SafePoint();
  51.171 -            JVMState* youngest_jvms = sfn->jvms();
  51.172 -            int max_depth = youngest_jvms->depth();
  51.173 -            for (int depth = 1; depth <= max_depth; depth++) {
  51.174 -              JVMState* jvms = youngest_jvms->of_depth(depth);
  51.175 -              int num_mon  = jvms->nof_monitors();
  51.176 -              // Loop over monitors
  51.177 -              for (int idx = 0; idx < num_mon; idx++) {
  51.178 -                Node* obj_node = sfn->monitor_obj(jvms, idx);
  51.179 -                Node* box_node = sfn->monitor_box(jvms, idx);
  51.180 -                if (box_node == oldbox && obj_node == obj) {
  51.181 -                  int j = jvms->monitor_box_offset(idx);
  51.182 -                  _igvn.hash_delete(u);
  51.183 -                  u->set_req(j, newbox);
  51.184 -                  next_edge = false;
  51.185 -                }
  51.186 -              } // for (int idx = 0;
  51.187 -            } // for (int depth = 1;
  51.188 -          } // if (u->is_SafePoint()
  51.189 -          if (next_edge) i++;
  51.190 -        } // for (uint i = 0; i < oldbox->outcnt();)
  51.191 -      } // if (!oldbox->is_eliminated())
  51.192 -  } // if (!alock->is_coarsened())
  51.193 +  if (alock->is_non_esc_obj()) { // Lock is used for non escaping object
  51.194 +    // Look for all locks of this object and mark them and
  51.195 +    // corresponding BoxLock nodes as eliminated.
  51.196 +    Node* obj = alock->obj_node();
  51.197 +    for (uint j = 0; j < obj->outcnt(); j++) {
  51.198 +      Node* o = obj->raw_out(j);
  51.199 +      if (o->is_AbstractLock() &&
  51.200 +          o->as_AbstractLock()->obj_node()->eqv_uncast(obj)) {
  51.201 +        alock = o->as_AbstractLock();
  51.202 +        Node* box = alock->box_node();
  51.203 +        // Replace old box node with new eliminated box for all users
  51.204 +        // of the same object and mark related locks as eliminated.
  51.205 +        mark_eliminated_box(box, obj);
  51.206 +      }
  51.207 +    }
  51.208 +  }
  51.209  }
  51.210  
  51.211  // we have determined that this lock/unlock can be eliminated, we simply
  51.212 @@ -1870,7 +1957,7 @@
  51.213      return false;
  51.214    }
  51.215  #ifdef ASSERT
  51.216 -  if (alock->is_Lock() && !alock->is_coarsened()) {
  51.217 +  if (!alock->is_coarsened()) {
  51.218      // Check that new "eliminated" BoxLock node is created.
  51.219      BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
  51.220      assert(oldbox->is_eliminated(), "should be done already");
  51.221 @@ -1962,6 +2049,8 @@
  51.222    Node* box = lock->box_node();
  51.223    Node* flock = lock->fastlock_node();
  51.224  
  51.225 +  assert(!box->as_BoxLock()->is_eliminated(), "sanity");
  51.226 +
  51.227    // Make the merge point
  51.228    Node *region;
  51.229    Node *mem_phi;
  51.230 @@ -2196,6 +2285,8 @@
  51.231    Node* obj = unlock->obj_node();
  51.232    Node* box = unlock->box_node();
  51.233  
  51.234 +  assert(!box->as_BoxLock()->is_eliminated(), "sanity");
  51.235 +
  51.236    // No need for a null check on unlock
  51.237  
  51.238    // Make the merge point
    52.1 --- a/src/share/vm/opto/macro.hpp	Sat Jan 21 23:02:40 2012 -0500
    52.2 +++ b/src/share/vm/opto/macro.hpp	Mon Jan 23 17:45:32 2012 -0800
    52.3 @@ -92,6 +92,7 @@
    52.4    void process_users_of_allocation(AllocateNode *alloc);
    52.5  
    52.6    void eliminate_card_mark(Node *cm);
    52.7 +  void mark_eliminated_box(Node* box, Node* obj);
    52.8    void mark_eliminated_locking_nodes(AbstractLockNode *alock);
    52.9    bool eliminate_locking_node(AbstractLockNode *alock);
   52.10    void expand_lock_node(LockNode *lock);
    53.1 --- a/src/share/vm/opto/memnode.cpp	Sat Jan 21 23:02:40 2012 -0500
    53.2 +++ b/src/share/vm/opto/memnode.cpp	Mon Jan 23 17:45:32 2012 -0800
    53.3 @@ -2201,7 +2201,7 @@
    53.4    // unsafe if I have intervening uses...  Also disallowed for StoreCM
    53.5    // since they must follow each StoreP operation.  Redundant StoreCMs
    53.6    // are eliminated just before matching in final_graph_reshape.
    53.7 -  if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address) &&
    53.8 +  if (mem->is_Store() && mem->in(MemNode::Address)->eqv_uncast(address) &&
    53.9        mem->Opcode() != Op_StoreCM) {
   53.10      // Looking at a dead closed cycle of memory?
   53.11      assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal");
   53.12 @@ -2274,16 +2274,16 @@
   53.13  
   53.14    // Load then Store?  Then the Store is useless
   53.15    if (val->is_Load() &&
   53.16 -      phase->eqv_uncast( val->in(MemNode::Address), adr ) &&
   53.17 -      phase->eqv_uncast( val->in(MemNode::Memory ), mem ) &&
   53.18 +      val->in(MemNode::Address)->eqv_uncast(adr) &&
   53.19 +      val->in(MemNode::Memory )->eqv_uncast(mem) &&
   53.20        val->as_Load()->store_Opcode() == Opcode()) {
   53.21      return mem;
   53.22    }
   53.23  
   53.24    // Two stores in a row of the same value?
   53.25    if (mem->is_Store() &&
   53.26 -      phase->eqv_uncast( mem->in(MemNode::Address), adr ) &&
   53.27 -      phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) &&
   53.28 +      mem->in(MemNode::Address)->eqv_uncast(adr) &&
   53.29 +      mem->in(MemNode::ValueIn)->eqv_uncast(val) &&
   53.30        mem->Opcode() == Opcode()) {
   53.31      return mem;
   53.32    }
    54.1 --- a/src/share/vm/opto/node.cpp	Sat Jan 21 23:02:40 2012 -0500
    54.2 +++ b/src/share/vm/opto/node.cpp	Mon Jan 23 17:45:32 2012 -0800
    54.3 @@ -833,8 +833,20 @@
    54.4  
    54.5  //---------------------------uncast_helper-------------------------------------
    54.6  Node* Node::uncast_helper(const Node* p) {
    54.7 -  uint max_depth = 3;
    54.8 -  for (uint i = 0; i < max_depth; i++) {
    54.9 +#ifdef ASSERT
   54.10 +  uint depth_count = 0;
   54.11 +  const Node* orig_p = p;
   54.12 +#endif
   54.13 +
   54.14 +  while (true) {
   54.15 +#ifdef ASSERT
   54.16 +    if (depth_count >= K) {
   54.17 +      orig_p->dump(4);
   54.18 +      if (p != orig_p)
   54.19 +        p->dump(1);
   54.20 +    }
   54.21 +    assert(depth_count++ < K, "infinite loop in Node::uncast_helper");
   54.22 +#endif
   54.23      if (p == NULL || p->req() != 2) {
   54.24        break;
   54.25      } else if (p->is_ConstraintCast()) {
    55.1 --- a/src/share/vm/opto/node.hpp	Sat Jan 21 23:02:40 2012 -0500
    55.2 +++ b/src/share/vm/opto/node.hpp	Mon Jan 23 17:45:32 2012 -0800
    55.3 @@ -429,6 +429,10 @@
    55.4  
    55.5    // Strip away casting.  (It is depth-limited.)
    55.6    Node* uncast() const;
    55.7 +  // Return whether two Nodes are equivalent, after stripping casting.
    55.8 +  bool eqv_uncast(const Node* n) const {
    55.9 +    return (this->uncast() == n->uncast());
   55.10 +  }
   55.11  
   55.12  private:
   55.13    static Node* uncast_helper(const Node* n);
    56.1 --- a/src/share/vm/opto/output.cpp	Sat Jan 21 23:02:40 2012 -0500
    56.2 +++ b/src/share/vm/opto/output.cpp	Mon Jan 23 17:45:32 2012 -0800
    56.3 @@ -924,10 +924,10 @@
    56.4          scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding());
    56.5        }
    56.6  
    56.7 -      OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
    56.8 +      OptoReg::Name box_reg = BoxLockNode::reg(box_node);
    56.9        Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg));
   56.10 -      while( !box_node->is_BoxLock() )  box_node = box_node->in(1);
   56.11 -      monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated()));
   56.12 +      bool eliminated = (box_node->is_BoxLock() && box_node->as_BoxLock()->is_eliminated());
   56.13 +      monarray->append(new MonitorValue(scval, basic_lock, eliminated));
   56.14      }
   56.15  
   56.16      // We dump the object pool first, since deoptimization reads it in first.
    57.1 --- a/src/share/vm/opto/parse1.cpp	Sat Jan 21 23:02:40 2012 -0500
    57.2 +++ b/src/share/vm/opto/parse1.cpp	Mon Jan 23 17:45:32 2012 -0800
    57.3 @@ -1604,7 +1604,16 @@
    57.4            continue;
    57.5          default:                // All normal stuff
    57.6            if (phi == NULL) {
    57.7 -            if (!check_elide_phi || !target->can_elide_SEL_phi(j)) {
    57.8 +            const JVMState* jvms = map()->jvms();
    57.9 +            if (EliminateNestedLocks &&
   57.10 +                jvms->is_mon(j) && jvms->is_monitor_box(j)) {
   57.11 +              // BoxLock nodes are not commoning.
   57.12 +              // Use old BoxLock node as merged box.
   57.13 +              assert(newin->jvms()->is_monitor_box(j), "sanity");
   57.14 +              // This assert also tests that nodes are BoxLock.
   57.15 +              assert(BoxLockNode::same_slot(n, m), "sanity");
   57.16 +              C->gvn_replace_by(n, m);
   57.17 +            } else if (!check_elide_phi || !target->can_elide_SEL_phi(j)) {
   57.18                phi = ensure_phi(j, nophi);
   57.19              }
   57.20            }
    58.1 --- a/src/share/vm/opto/phaseX.hpp	Sat Jan 21 23:02:40 2012 -0500
    58.2 +++ b/src/share/vm/opto/phaseX.hpp	Mon Jan 23 17:45:32 2012 -0800
    58.3 @@ -256,11 +256,6 @@
    58.4    // For pessimistic optimizations this is simply pointer equivalence.
    58.5    bool eqv(const Node* n1, const Node* n2) const { return n1 == n2; }
    58.6  
    58.7 -  // Return whether two Nodes are equivalent, after stripping casting.
    58.8 -  bool eqv_uncast(const Node* n1, const Node* n2) const {
    58.9 -    return eqv(n1->uncast(), n2->uncast());
   58.10 -  }
   58.11 -
   58.12    // For pessimistic passes, the return type must monotonically narrow.
   58.13    // For optimistic  passes, the return type must monotonically widen.
   58.14    // It is possible to get into a "death march" in either type of pass,
    59.1 --- a/src/share/vm/opto/postaloc.cpp	Sat Jan 21 23:02:40 2012 -0500
    59.2 +++ b/src/share/vm/opto/postaloc.cpp	Mon Jan 23 17:45:32 2012 -0800
    59.3 @@ -89,32 +89,62 @@
    59.4    return blk_adjust;
    59.5  }
    59.6  
    59.7 +#ifdef ASSERT
    59.8 +static bool expected_yanked_node(Node *old, Node *orig_old) {
    59.9 +  // This code is expected only next original nodes:
   59.10 +  // - load from constant table node which may have next data input nodes:
   59.11 +  //     MachConstantBase, Phi, MachTemp, MachSpillCopy
   59.12 +  // - load constant node which may have next data input nodes:
   59.13 +  //     MachTemp, MachSpillCopy
   59.14 +  // - MachSpillCopy
   59.15 +  // - MachProj and Copy dead nodes
   59.16 +  if (old->is_MachSpillCopy()) {
   59.17 +    return true;
   59.18 +  } else if (old->is_Con()) {
   59.19 +    return true;
   59.20 +  } else if (old->is_MachProj()) { // Dead kills projection of Con node
   59.21 +    return (old == orig_old);
   59.22 +  } else if (old->is_Copy()) {     // Dead copy of a callee-save value
   59.23 +    return (old == orig_old);
   59.24 +  } else if (old->is_MachTemp()) {
   59.25 +    return orig_old->is_Con();
   59.26 +  } else if (old->is_Phi() || old->is_MachConstantBase()) {
   59.27 +    return (orig_old->is_Con() && orig_old->is_MachConstant());
   59.28 +  }
   59.29 +  return false;
   59.30 +}
   59.31 +#endif
   59.32 +
   59.33  //------------------------------yank_if_dead-----------------------------------
   59.34 -// Removed an edge from 'old'.  Yank if dead.  Return adjustment counts to
   59.35 +// Removed edges from 'old'.  Yank if dead.  Return adjustment counts to
   59.36  // iterators in the current block.
   59.37 -int PhaseChaitin::yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
   59.38 +int PhaseChaitin::yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block,
   59.39 +                                       Node_List *value, Node_List *regnd) {
   59.40    int blk_adjust=0;
   59.41 -  while (old->outcnt() == 0 && old != C->top()) {
   59.42 +  if (old->outcnt() == 0 && old != C->top()) {
   59.43 +#ifdef ASSERT
   59.44 +    if (!expected_yanked_node(old, orig_old)) {
   59.45 +      tty->print_cr("==============================================");
   59.46 +      tty->print_cr("orig_old:");
   59.47 +      orig_old->dump();
   59.48 +      tty->print_cr("old:");
   59.49 +      old->dump();
   59.50 +      assert(false, "unexpected yanked node");
   59.51 +    }
   59.52 +    if (old->is_Con())
   59.53 +      orig_old = old; // Reset to satisfy expected nodes checks.
   59.54 +#endif
   59.55      blk_adjust += yank(old, current_block, value, regnd);
   59.56  
   59.57 -    Node *tmp = NULL;
   59.58      for (uint i = 1; i < old->req(); i++) {
   59.59 -      if (old->in(i)->is_MachTemp()) {
   59.60 -        // handle TEMP inputs
   59.61 -        Node* machtmp = old->in(i);
   59.62 -        if (machtmp->outcnt() == 1) {
   59.63 -          assert(machtmp->unique_out() == old, "sanity");
   59.64 -          blk_adjust += yank(machtmp, current_block, value, regnd);
   59.65 -          machtmp->disconnect_inputs(NULL);
   59.66 -        }
   59.67 -      } else {
   59.68 -        assert(tmp == NULL, "can't handle more non MachTemp inputs");
   59.69 -        tmp = old->in(i);
   59.70 +      Node* n = old->in(i);
   59.71 +      if (n != NULL) {
   59.72 +        old->set_req(i, NULL);
   59.73 +        blk_adjust += yank_if_dead_recurse(n, orig_old, current_block, value, regnd);
   59.74        }
   59.75      }
   59.76 +    // Disconnect control and remove precedence edges if any exist
   59.77      old->disconnect_inputs(NULL);
   59.78 -    if( !tmp ) break;
   59.79 -    old = tmp;
   59.80    }
   59.81    return blk_adjust;
   59.82  }
    60.1 --- a/src/share/vm/opto/subnode.cpp	Sat Jan 21 23:02:40 2012 -0500
    60.2 +++ b/src/share/vm/opto/subnode.cpp	Mon Jan 23 17:45:32 2012 -0800
    60.3 @@ -91,7 +91,7 @@
    60.4  
    60.5    // Not correct for SubFnode and AddFNode (must check for infinity)
    60.6    // Equal?  Subtract is zero
    60.7 -  if (phase->eqv_uncast(in1, in2))  return add_id();
    60.8 +  if (in1->eqv_uncast(in2))  return add_id();
    60.9  
   60.10    // Either input is BOTTOM ==> the result is the local BOTTOM
   60.11    if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
    61.1 --- a/src/share/vm/runtime/arguments.cpp	Sat Jan 21 23:02:40 2012 -0500
    61.2 +++ b/src/share/vm/runtime/arguments.cpp	Mon Jan 23 17:45:32 2012 -0800
    61.3 @@ -3160,6 +3160,9 @@
    61.4    if (!UseBiasedLocking || EmitSync != 0) {
    61.5      UseOptoBiasInlining = false;
    61.6    }
    61.7 +  if (!EliminateLocks) {
    61.8 +    EliminateNestedLocks = false;
    61.9 +  }
   61.10  #endif
   61.11  
   61.12    if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
    62.1 --- a/src/share/vm/runtime/deoptimization.cpp	Sat Jan 21 23:02:40 2012 -0500
    62.2 +++ b/src/share/vm/runtime/deoptimization.cpp	Mon Jan 23 17:45:32 2012 -0800
    62.3 @@ -211,7 +211,7 @@
    62.4  #ifdef COMPILER2
    62.5    // Reallocate the non-escaping objects and restore their fields. Then
    62.6    // relock objects if synchronization on them was eliminated.
    62.7 -  if (DoEscapeAnalysis) {
    62.8 +  if (DoEscapeAnalysis || EliminateNestedLocks) {
    62.9      if (EliminateAllocations) {
   62.10        assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
   62.11        GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
    63.1 --- a/src/share/vm/runtime/vmStructs.cpp	Sat Jan 21 23:02:40 2012 -0500
    63.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Mon Jan 23 17:45:32 2012 -0800
    63.3 @@ -307,7 +307,7 @@
    63.4    nonstatic_field(instanceKlass,               _static_field_size,                            int)                                   \
    63.5    nonstatic_field(instanceKlass,               _static_oop_field_count,                       u2)                                   \
    63.6    nonstatic_field(instanceKlass,               _nonstatic_oop_map_size,                       int)                                   \
    63.7 -  nonstatic_field(instanceKlass,               _misc_flags,                                   u1)                                    \
    63.8 +  nonstatic_field(instanceKlass,               _is_marked_dependent,                          bool)                                  \
    63.9    nonstatic_field(instanceKlass,               _minor_version,                                u2)                                    \
   63.10    nonstatic_field(instanceKlass,               _major_version,                                u2)                                    \
   63.11    nonstatic_field(instanceKlass,               _init_state,                                   u1)                                    \
   63.12 @@ -2386,7 +2386,6 @@
   63.13    declare_constant(instanceKlass::being_initialized)                      \
   63.14    declare_constant(instanceKlass::fully_initialized)                      \
   63.15    declare_constant(instanceKlass::initialization_error)                   \
   63.16 -  declare_constant(instanceKlass::IS_MARKED_DEPENDENT)                    \
   63.17                                                                            \
   63.18    /*********************************/                                     \
   63.19    /* Symbol* - symbol max length */                                     \
    64.1 --- a/src/share/vm/utilities/decoder.cpp	Sat Jan 21 23:02:40 2012 -0500
    64.2 +++ b/src/share/vm/utilities/decoder.cpp	Mon Jan 23 17:45:32 2012 -0800
    64.3 @@ -24,80 +24,85 @@
    64.4  
    64.5  #include "precompiled.hpp"
    64.6  #include "prims/jvm.h"
    64.7 +#include "runtime/mutexLocker.hpp"
    64.8  #include "utilities/decoder.hpp"
    64.9  
   64.10 -Decoder::decoder_status  Decoder::_decoder_status = Decoder::no_error;
   64.11 -bool                     Decoder::_initialized = false;
   64.12 +#if defined(_WINDOWS)
   64.13 +  #include "decoder_windows.hpp"
   64.14 +#elif defined(__APPLE__)
   64.15 +  #include "decoder_machO.hpp"
   64.16 +#else
   64.17 +  #include "decoder_elf.hpp"
   64.18 +#endif
   64.19  
   64.20 -#if !defined(_WINDOWS) && !defined(__APPLE__)
   64.21 +NullDecoder*  Decoder::_decoder = NULL;
   64.22 +NullDecoder   Decoder::_do_nothing_decoder;
   64.23 +Mutex*           Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
   64.24 +                                "DecoderLock");
   64.25  
   64.26 -// Implementation of common functionalities among Solaris and Linux
   64.27 -#include "utilities/elfFile.hpp"
   64.28 +// _decoder_lock should already acquired before enter this method
   64.29 +NullDecoder* Decoder::get_decoder() {
   64.30 +  assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
   64.31 +    "Require DecoderLock to enter");
   64.32  
   64.33 -ElfFile* Decoder::_opened_elf_files = NULL;
   64.34 +  if (_decoder != NULL) {
   64.35 +    return _decoder;
   64.36 +  }
   64.37 +
   64.38 +  // Decoder is a secondary service. Although, it is good to have,
   64.39 +  // but we can live without it.
   64.40 +#if defined(_WINDOWS)
   64.41 +  _decoder = new (std::nothrow) WindowsDecoder();
   64.42 +#elif defined (__APPLE__)
   64.43 +    _decoder = new (std::nothrow)MachODecoder();
   64.44 +#else
   64.45 +    _decoder = new (std::nothrow)ElfDecoder();
   64.46 +#endif
   64.47 +
   64.48 +  if (_decoder == NULL || _decoder->has_error()) {
   64.49 +    if (_decoder != NULL) {
   64.50 +      delete _decoder;
   64.51 +    }
   64.52 +    _decoder = &_do_nothing_decoder;
   64.53 +  }
   64.54 +  return _decoder;
   64.55 +}
   64.56 +
   64.57 +bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
   64.58 +  assert(_decoder_lock != NULL, "Just check");
   64.59 +  MutexLockerEx locker(_decoder_lock, true);
   64.60 +  NullDecoder* decoder = get_decoder();
   64.61 +  assert(decoder != NULL, "null decoder");
   64.62 +
   64.63 +  return decoder->decode(addr, buf, buflen, offset, modulepath);
   64.64 +}
   64.65 +
   64.66 +bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
   64.67 +  assert(_decoder_lock != NULL, "Just check");
   64.68 +  MutexLockerEx locker(_decoder_lock, true);
   64.69 +  NullDecoder* decoder = get_decoder();
   64.70 +  assert(decoder != NULL, "null decoder");
   64.71 +  return decoder->demangle(symbol, buf, buflen);
   64.72 +}
   64.73  
   64.74  bool Decoder::can_decode_C_frame_in_vm() {
   64.75 -  return true;
   64.76 +  assert(_decoder_lock != NULL, "Just check");
   64.77 +  MutexLockerEx locker(_decoder_lock, true);
   64.78 +  NullDecoder* decoder = get_decoder();
   64.79 +  assert(decoder != NULL, "null decoder");
   64.80 +  return decoder->can_decode_C_frame_in_vm();
   64.81  }
   64.82  
   64.83 -void Decoder::initialize() {
   64.84 -  _initialized = true;
   64.85 +// shutdown real decoder and replace it with
   64.86 +// _do_nothing_decoder
   64.87 +void Decoder::shutdown() {
   64.88 +  assert(_decoder_lock != NULL, "Just check");
   64.89 +  MutexLockerEx locker(_decoder_lock, true);
   64.90 +
   64.91 +  if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
   64.92 +    delete _decoder;
   64.93 +  }
   64.94 +
   64.95 +  _decoder = &_do_nothing_decoder;
   64.96  }
   64.97  
   64.98 -void Decoder::uninitialize() {
   64.99 -  if (_opened_elf_files != NULL) {
  64.100 -    delete _opened_elf_files;
  64.101 -    _opened_elf_files = NULL;
  64.102 -  }
  64.103 -  _initialized = false;
  64.104 -}
  64.105 -
  64.106 -Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
  64.107 -  if (_decoder_status != no_error) {
  64.108 -    return _decoder_status;
  64.109 -  }
  64.110 -
  64.111 -  ElfFile* file = get_elf_file(filepath);
  64.112 -  if (_decoder_status != no_error) {
  64.113 -    return _decoder_status;
  64.114 -  }
  64.115 -
  64.116 -  const char* symbol = file->decode(addr, offset);
  64.117 -  if (file->get_status() == out_of_memory) {
  64.118 -    _decoder_status = out_of_memory;
  64.119 -    return _decoder_status;
  64.120 -  } else if (symbol != NULL) {
  64.121 -    if (!demangle(symbol, buf, buflen)) {
  64.122 -      jio_snprintf(buf, buflen, "%s", symbol);
  64.123 -    }
  64.124 -    return no_error;
  64.125 -  } else {
  64.126 -    return symbol_not_found;
  64.127 -  }
  64.128 -}
  64.129 -
  64.130 -ElfFile* Decoder::get_elf_file(const char* filepath) {
  64.131 -  if (_decoder_status != no_error) {
  64.132 -    return NULL;
  64.133 -  }
  64.134 -  ElfFile* file = _opened_elf_files;
  64.135 -  while (file != NULL) {
  64.136 -    if (file->same_elf_file(filepath)) {
  64.137 -      return file;
  64.138 -    }
  64.139 -    file = file->m_next;
  64.140 -  }
  64.141 -
  64.142 -  file = new ElfFile(filepath);
  64.143 -  if (file == NULL) {
  64.144 -    _decoder_status = out_of_memory;
  64.145 -  }
  64.146 -  if (_opened_elf_files != NULL) {
  64.147 -    file->m_next = _opened_elf_files;
  64.148 -  }
  64.149 -
  64.150 -  _opened_elf_files = file;
  64.151 -  return file;
  64.152 -}
  64.153 -
  64.154 -#endif
    65.1 --- a/src/share/vm/utilities/decoder.hpp	Sat Jan 21 23:02:40 2012 -0500
    65.2 +++ b/src/share/vm/utilities/decoder.hpp	Mon Jan 23 17:45:32 2012 -0800
    65.3 @@ -1,5 +1,5 @@
    65.4  /*
    65.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    65.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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 @@ -23,83 +23,78 @@
   65.11   */
   65.12  
   65.13  
   65.14 -#ifndef __DECODER_HPP
   65.15 -#define __DECODER_HPP
   65.16 +#ifndef SHARE_VM_UTILITIES_DECODER_HPP
   65.17 +#define SHARE_VM_UTILITIES_DECODER_HPP
   65.18  
   65.19  #include "memory/allocation.hpp"
   65.20 +#include "runtime/mutex.hpp"
   65.21  
   65.22 -#ifdef _WINDOWS
   65.23 -#include <windows.h>
   65.24 -#include <imagehlp.h>
   65.25 -
   65.26 -// functions needed for decoding symbols
   65.27 -typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
   65.28 -typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
   65.29 -typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
   65.30 -typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
   65.31 -
   65.32 -#elif defined(__APPLE__)
   65.33 -
   65.34 -#else
   65.35 -
   65.36 -class ElfFile;
   65.37 -
   65.38 -#endif // _WINDOWS
   65.39 -
   65.40 -
   65.41 -class Decoder: public StackObj {
   65.42 -
   65.43 - public:
   65.44 +class NullDecoder: public CHeapObj {
   65.45 +public:
   65.46    // status code for decoding native C frame
   65.47    enum decoder_status {
   65.48 -         no_error,             // successfully decoded frames
   65.49 +         not_available = -10,  // real decoder is not available
   65.50 +         no_error = 0,         // successfully decoded frames
   65.51           out_of_memory,        // out of memory
   65.52           file_invalid,         // invalid elf file
   65.53           file_not_found,       // could not found symbol file (on windows), such as jvm.pdb or jvm.map
   65.54           helper_not_found,     // could not load dbghelp.dll (Windows only)
   65.55           helper_func_error,    // decoding functions not found (Windows only)
   65.56 -         helper_init_error,    // SymInitialize failed (Windows only)
   65.57 -         symbol_not_found      // could not find the symbol
   65.58 +         helper_init_error     // SymInitialize failed (Windows only)
   65.59    };
   65.60  
   65.61 - public:
   65.62 -  Decoder() { initialize(); };
   65.63 -  ~Decoder() { uninitialize(); };
   65.64 +  NullDecoder() {
   65.65 +    _decoder_status = not_available;
   65.66 +  }
   65.67  
   65.68 +  ~NullDecoder() {};
   65.69 +
   65.70 +  virtual bool decode(address pc, char* buf, int buflen, int* offset,
   65.71 +    const char* modulepath = NULL) {
   65.72 +    return false;
   65.73 +  }
   65.74 +
   65.75 +  virtual bool demangle(const char* symbol, char* buf, int buflen) {
   65.76 +    return false;
   65.77 +  }
   65.78 +
   65.79 +  virtual bool can_decode_C_frame_in_vm() const {
   65.80 +    return false;
   65.81 +  }
   65.82 +
   65.83 +  virtual decoder_status status() const {
   65.84 +    return _decoder_status;
   65.85 +  }
   65.86 +
   65.87 +  virtual bool has_error() const {
   65.88 +    return is_error(_decoder_status);
   65.89 +  }
   65.90 +
   65.91 +  static bool is_error(decoder_status status) {
   65.92 +    return (status > 0);
   65.93 +  }
   65.94 +
   65.95 +protected:
   65.96 +  decoder_status  _decoder_status;
   65.97 +};
   65.98 +
   65.99 +
  65.100 +class Decoder: AllStatic {
  65.101 +public:
  65.102 +  static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
  65.103 +  static bool demangle(const char* symbol, char* buf, int buflen);
  65.104    static bool can_decode_C_frame_in_vm();
  65.105  
  65.106 -  static void initialize();
  65.107 -  static void uninitialize();
  65.108 +  static void shutdown();
  65.109 +protected:
  65.110 +  static NullDecoder* get_decoder();
  65.111  
  65.112 -#ifdef _WINDOWS
  65.113 -  static decoder_status    decode(address addr, char *buf, int buflen, int *offset);
  65.114 -#else
  65.115 -  static decoder_status    decode(address addr, const char* filepath, char *buf, int buflen, int *offset);
  65.116 -#endif
  65.117 +private:
  65.118 +  static NullDecoder*     _decoder;
  65.119 +  static NullDecoder      _do_nothing_decoder;
  65.120  
  65.121 -  static bool              demangle(const char* symbol, char *buf, int buflen);
  65.122 -
  65.123 -  static decoder_status    get_status() { return _decoder_status; };
  65.124 -
  65.125 -#if !defined(_WINDOWS) && !defined(__APPLE__)
  65.126 - private:
  65.127 -  static ElfFile*         get_elf_file(const char* filepath);
  65.128 -#endif // _WINDOWS
  65.129 -
  65.130 -
  65.131 - private:
  65.132 -  static decoder_status     _decoder_status;
  65.133 -  static bool               _initialized;
  65.134 -
  65.135 -#ifdef _WINDOWS
  65.136 -  static HMODULE                   _dbghelp_handle;
  65.137 -  static bool                      _can_decode_in_vm;
  65.138 -  static pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
  65.139 -  static pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
  65.140 -#elif __APPLE__
  65.141 -#else
  65.142 -  static ElfFile*                  _opened_elf_files;
  65.143 -#endif // _WINDOWS
  65.144 +protected:
  65.145 +  static Mutex*       _decoder_lock;
  65.146  };
  65.147  
  65.148 -#endif // __DECODER_HPP
  65.149 +#endif // SHARE_VM_UTILITIES_DECODER_HPP
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/src/share/vm/utilities/decoder_elf.cpp	Mon Jan 23 17:45:32 2012 -0800
    66.3 @@ -0,0 +1,76 @@
    66.4 +/*
    66.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    66.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    66.7 + *
    66.8 + * This code is free software; you can redistribute it and/or modify it
    66.9 + * under the terms of the GNU General Public License version 2 only, as
   66.10 + * published by the Free Software Foundation.
   66.11 + *
   66.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   66.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   66.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   66.15 + * version 2 for more details (a copy is included in the LICENSE file that
   66.16 + * accompanied this code).
   66.17 + *
   66.18 + * You should have received a copy of the GNU General Public License version
   66.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   66.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   66.21 + *
   66.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   66.23 + * or visit www.oracle.com if you need additional information or have any
   66.24 + * questions.
   66.25 + *
   66.26 + */
   66.27 +
   66.28 +#include "precompiled.hpp"
   66.29 +
   66.30 +#if !defined(_WINDOWS) && !defined(__APPLE__)
   66.31 +#include "decoder_elf.hpp"
   66.32 +
   66.33 +ElfDecoder::~ElfDecoder() {
   66.34 +  if (_opened_elf_files != NULL) {
   66.35 +    delete _opened_elf_files;
   66.36 +    _opened_elf_files = NULL;
   66.37 +  }
   66.38 +}
   66.39 +
   66.40 +bool ElfDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* filepath) {
   66.41 +  assert(filepath, "null file path");
   66.42 +  assert(buf != NULL && buflen > 0, "Invalid buffer");
   66.43 +  if (has_error()) return false;
   66.44 +  ElfFile* file = get_elf_file(filepath);
   66.45 +  if (file == NULL) {
   66.46 +    return false;
   66.47 +  }
   66.48 +
   66.49 +  if (!file->decode(addr, buf, buflen, offset)) {
   66.50 +    return false;
   66.51 +  }
   66.52 +  if (buf[0] != '\0') {
   66.53 +    demangle(buf, buf, buflen);
   66.54 +  }
   66.55 +  return true;
   66.56 +}
   66.57 +
   66.58 +ElfFile* ElfDecoder::get_elf_file(const char* filepath) {
   66.59 +  ElfFile* file;
   66.60 +
   66.61 +  file = _opened_elf_files;
   66.62 +  while (file != NULL) {
   66.63 +    if (file->same_elf_file(filepath)) {
   66.64 +      return file;
   66.65 +    }
   66.66 +    file = file->next();
   66.67 +  }
   66.68 +
   66.69 +  file = new (std::nothrow)ElfFile(filepath);
   66.70 +  if (file != NULL) {
   66.71 +    if (_opened_elf_files != NULL) {
   66.72 +      file->set_next(_opened_elf_files);
   66.73 +    }
   66.74 +    _opened_elf_files = file;
   66.75 +  }
   66.76 +
   66.77 +  return file;
   66.78 +}
   66.79 +#endif
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/src/share/vm/utilities/decoder_elf.hpp	Mon Jan 23 17:45:32 2012 -0800
    67.3 @@ -0,0 +1,55 @@
    67.4 +/*
    67.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    67.7 + *
    67.8 + * This code is free software; you can redistribute it and/or modify it
    67.9 + * under the terms of the GNU General Public License version 2 only, as
   67.10 + * published by the Free Software Foundation.
   67.11 + *
   67.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   67.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   67.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   67.15 + * version 2 for more details (a copy is included in the LICENSE file that
   67.16 + * accompanied this code).
   67.17 + *
   67.18 + * You should have received a copy of the GNU General Public License version
   67.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   67.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   67.21 + *
   67.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   67.23 + * or visit www.oracle.com if you need additional information or have any
   67.24 + * questions.
   67.25 + *
   67.26 + */
   67.27 +
   67.28 +#ifndef SHARE_VM_UTILITIES_DECODER_ELF_HPP
   67.29 +#define SHARE_VM_UTILITIES_DECODER_ELF_HPP
   67.30 +
   67.31 +#if !defined(_WINDOWS) && !defined(__APPLE__)
   67.32 +
   67.33 +#include "utilities/decoder.hpp"
   67.34 +#include "utilities/elfFile.hpp"
   67.35 +
   67.36 +class ElfDecoder: public NullDecoder {
   67.37 +
   67.38 +public:
   67.39 +  ElfDecoder() {
   67.40 +    _opened_elf_files = NULL;
   67.41 +    _decoder_status = no_error;
   67.42 +  }
   67.43 +  ~ElfDecoder();
   67.44 +
   67.45 +  bool can_decode_C_frame_in_vm() const { return true; }
   67.46 +
   67.47 +  bool demangle(const char* symbol, char *buf, int buflen);
   67.48 +  bool decode(address addr, char *buf, int buflen, int* offset, const char* filepath = NULL);
   67.49 +
   67.50 +private:
   67.51 +  ElfFile*         get_elf_file(const char* filepath);
   67.52 +
   67.53 +private:
   67.54 +  ElfFile*         _opened_elf_files;
   67.55 +};
   67.56 +
   67.57 +#endif
   67.58 +#endif // SHARE_VM_UTILITIES_DECODER_ELF_HPP
    68.1 --- a/src/share/vm/utilities/elfFile.cpp	Sat Jan 21 23:02:40 2012 -0500
    68.2 +++ b/src/share/vm/utilities/elfFile.cpp	Mon Jan 23 17:45:32 2012 -0800
    68.3 @@ -44,7 +44,7 @@
    68.4    m_string_tables = NULL;
    68.5    m_symbol_tables = NULL;
    68.6    m_next = NULL;
    68.7 -  m_status = Decoder::no_error;
    68.8 +  m_status = NullDecoder::no_error;
    68.9  
   68.10    int len = strlen(filepath) + 1;
   68.11    m_filepath = (const char*)os::malloc(len * sizeof(char));
   68.12 @@ -54,10 +54,10 @@
   68.13      if (m_file != NULL) {
   68.14        load_tables();
   68.15      } else {
   68.16 -      m_status = Decoder::file_not_found;
   68.17 +      m_status = NullDecoder::file_not_found;
   68.18      }
   68.19    } else {
   68.20 -    m_status = Decoder::out_of_memory;
   68.21 +    m_status = NullDecoder::out_of_memory;
   68.22    }
   68.23  }
   68.24  
   68.25 @@ -96,41 +96,41 @@
   68.26  
   68.27  bool ElfFile::load_tables() {
   68.28    assert(m_file, "file not open");
   68.29 -  assert(m_status == Decoder::no_error, "already in error");
   68.30 +  assert(!NullDecoder::is_error(m_status), "already in error");
   68.31  
   68.32    // read elf file header
   68.33    if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
   68.34 -    m_status = Decoder::file_invalid;
   68.35 +    m_status = NullDecoder::file_invalid;
   68.36      return false;
   68.37    }
   68.38  
   68.39    if (!is_elf_file(m_elfHdr)) {
   68.40 -    m_status = Decoder::file_invalid;
   68.41 +    m_status = NullDecoder::file_invalid;
   68.42      return false;
   68.43    }
   68.44  
   68.45    // walk elf file's section headers, and load string tables
   68.46    Elf_Shdr shdr;
   68.47    if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
   68.48 -    if (m_status != Decoder::no_error) return false;
   68.49 +    if (NullDecoder::is_error(m_status)) return false;
   68.50  
   68.51      for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
   68.52        if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
   68.53 -        m_status = Decoder::file_invalid;
   68.54 +        m_status = NullDecoder::file_invalid;
   68.55          return false;
   68.56        }
   68.57        // string table
   68.58        if (shdr.sh_type == SHT_STRTAB) {
   68.59          ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
   68.60          if (table == NULL) {
   68.61 -          m_status = Decoder::out_of_memory;
   68.62 +          m_status = NullDecoder::out_of_memory;
   68.63            return false;
   68.64          }
   68.65          add_string_table(table);
   68.66        } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
   68.67          ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
   68.68          if (table == NULL) {
   68.69 -          m_status = Decoder::out_of_memory;
   68.70 +          m_status = NullDecoder::out_of_memory;
   68.71            return false;
   68.72          }
   68.73          add_symbol_table(table);
   68.74 @@ -140,32 +140,33 @@
   68.75    return true;
   68.76  }
   68.77  
   68.78 -const char* ElfFile::decode(address addr, int* offset) {
   68.79 +bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
   68.80    // something already went wrong, just give up
   68.81 -  if (m_status != Decoder::no_error) {
   68.82 -    return NULL;
   68.83 +  if (NullDecoder::is_error(m_status)) {
   68.84 +    return false;
   68.85    }
   68.86 -
   68.87    ElfSymbolTable* symbol_table = m_symbol_tables;
   68.88    int string_table_index;
   68.89    int pos_in_string_table;
   68.90    int off = INT_MAX;
   68.91    bool found_symbol = false;
   68.92    while (symbol_table != NULL) {
   68.93 -    if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
   68.94 +    if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
   68.95        found_symbol = true;
   68.96      }
   68.97      symbol_table = symbol_table->m_next;
   68.98    }
   68.99 -  if (!found_symbol) return NULL;
  68.100 +  if (!found_symbol) return false;
  68.101  
  68.102    ElfStringTable* string_table = get_string_table(string_table_index);
  68.103 +
  68.104    if (string_table == NULL) {
  68.105 -    m_status = Decoder::file_invalid;
  68.106 -    return NULL;
  68.107 +    m_status = NullDecoder::file_invalid;
  68.108 +    return false;
  68.109    }
  68.110    if (offset) *offset = off;
  68.111 -  return string_table->string_at(pos_in_string_table);
  68.112 +
  68.113 +  return string_table->string_at(pos_in_string_table, buf, buflen);
  68.114  }
  68.115  
  68.116  
    69.1 --- a/src/share/vm/utilities/elfFile.hpp	Sat Jan 21 23:02:40 2012 -0500
    69.2 +++ b/src/share/vm/utilities/elfFile.hpp	Mon Jan 23 17:45:32 2012 -0800
    69.3 @@ -1,5 +1,5 @@
    69.4  /*
    69.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    69.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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 @@ -22,8 +22,8 @@
   69.11   *
   69.12   */
   69.13  
   69.14 -#ifndef __ELF_FILE_HPP
   69.15 -#define __ELF_FILE_HPP
   69.16 +#ifndef SHARE_VM_UTILITIES_ELF_FILE_HPP
   69.17 +#define SHARE_VM_UTILITIES_ELF_FILE_HPP
   69.18  
   69.19  #if !defined(_WINDOWS) && !defined(__APPLE__)
   69.20  
   69.21 @@ -83,12 +83,12 @@
   69.22  // part of code to be very defensive, and bait out if anything went wrong.
   69.23  
   69.24  class ElfFile: public CHeapObj {
   69.25 -  friend class Decoder;
   69.26 +  friend class ElfDecoder;
   69.27   public:
   69.28    ElfFile(const char* filepath);
   69.29    ~ElfFile();
   69.30  
   69.31 -  const char* decode(address addr, int* offset);
   69.32 +  bool decode(address addr, char* buf, int buflen, int* offset);
   69.33    const char* filepath() {
   69.34      return m_filepath;
   69.35    }
   69.36 @@ -99,7 +99,7 @@
   69.37      return (m_filepath && !strcmp(filepath, m_filepath));
   69.38    }
   69.39  
   69.40 -  Decoder::decoder_status get_status() {
   69.41 +  NullDecoder::decoder_status get_status() {
   69.42      return m_status;
   69.43    }
   69.44  
   69.45 @@ -119,8 +119,9 @@
   69.46    // return a string table at specified section index
   69.47    ElfStringTable* get_string_table(int index);
   69.48  
   69.49 -  // look up an address and return the nearest symbol
   69.50 -  const char* look_up(Elf_Shdr shdr, address addr, int* offset);
   69.51 +protected:
   69.52 +   ElfFile*  next() const { return m_next; }
   69.53 +   void set_next(ElfFile* file) { m_next = file; }
   69.54  
   69.55   protected:
   69.56      ElfFile*         m_next;
   69.57 @@ -131,17 +132,17 @@
   69.58    FILE* m_file;
   69.59  
   69.60    // Elf header
   69.61 -  Elf_Ehdr            m_elfHdr;
   69.62 +  Elf_Ehdr                     m_elfHdr;
   69.63  
   69.64    // symbol tables
   69.65 -  ElfSymbolTable*     m_symbol_tables;
   69.66 +  ElfSymbolTable*              m_symbol_tables;
   69.67  
   69.68    // string tables
   69.69 -  ElfStringTable*     m_string_tables;
   69.70 +  ElfStringTable*              m_string_tables;
   69.71  
   69.72 -  Decoder::decoder_status  m_status;
   69.73 +  NullDecoder::decoder_status  m_status;
   69.74  };
   69.75  
   69.76  #endif // _WINDOWS
   69.77  
   69.78 -#endif // __ELF_FILE_HPP
   69.79 +#endif // SHARE_VM_UTILITIES_ELF_FILE_HPP
    70.1 --- a/src/share/vm/utilities/elfStringTable.cpp	Sat Jan 21 23:02:40 2012 -0500
    70.2 +++ b/src/share/vm/utilities/elfStringTable.cpp	Mon Jan 23 17:45:32 2012 -0800
    70.3 @@ -38,7 +38,7 @@
    70.4    m_index = index;
    70.5    m_next = NULL;
    70.6    m_file = file;
    70.7 -  m_status = Decoder::no_error;
    70.8 +  m_status = NullDecoder::no_error;
    70.9  
   70.10    // try to load the string table
   70.11    long cur_offset = ftell(file);
   70.12 @@ -48,7 +48,7 @@
   70.13      if (fseek(file, shdr.sh_offset, SEEK_SET) ||
   70.14        fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
   70.15        fseek(file, cur_offset, SEEK_SET)) {
   70.16 -      m_status = Decoder::file_invalid;
   70.17 +      m_status = NullDecoder::file_invalid;
   70.18        os::free((void*)m_table);
   70.19        m_table = NULL;
   70.20      }
   70.21 @@ -67,22 +67,23 @@
   70.22    }
   70.23  }
   70.24  
   70.25 -const char* ElfStringTable::string_at(int pos) {
   70.26 -  if (m_status != Decoder::no_error) {
   70.27 -    return NULL;
   70.28 +bool ElfStringTable::string_at(int pos, char* buf, int buflen) {
   70.29 +  if (NullDecoder::is_error(m_status)) {
   70.30 +    return false;
   70.31    }
   70.32    if (m_table != NULL) {
   70.33 -    return (const char*)(m_table + pos);
   70.34 +    jio_snprintf(buf, buflen, "%s", (const char*)(m_table + pos));
   70.35 +    return true;
   70.36    } else {
   70.37      long cur_pos = ftell(m_file);
   70.38      if (cur_pos == -1 ||
   70.39        fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
   70.40 -      fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 ||
   70.41 +      fread(buf, 1, buflen, m_file) <= 0 ||
   70.42        fseek(m_file, cur_pos, SEEK_SET)) {
   70.43 -      m_status = Decoder::file_invalid;
   70.44 -      return NULL;
   70.45 +      m_status = NullDecoder::file_invalid;
   70.46 +      return false;
   70.47      }
   70.48 -    return (const char*)m_symbol;
   70.49 +    return true;
   70.50    }
   70.51  }
   70.52  
    71.1 --- a/src/share/vm/utilities/elfStringTable.hpp	Sat Jan 21 23:02:40 2012 -0500
    71.2 +++ b/src/share/vm/utilities/elfStringTable.hpp	Mon Jan 23 17:45:32 2012 -0800
    71.3 @@ -1,5 +1,5 @@
    71.4  /*
    71.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    71.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    71.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    71.8   *
    71.9   * This code is free software; you can redistribute it and/or modify it
   71.10 @@ -22,8 +22,8 @@
   71.11   *
   71.12   */
   71.13  
   71.14 -#ifndef __ELF_STRING_TABLE_HPP
   71.15 -#define __ELF_STRING_TABLE_HPP
   71.16 +#ifndef SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
   71.17 +#define SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
   71.18  
   71.19  #if !defined(_WINDOWS) && !defined(__APPLE__)
   71.20  
   71.21 @@ -35,9 +35,6 @@
   71.22  // The string table represents a string table section in an elf file.
   71.23  // Whenever there is enough memory, it will load whole string table as
   71.24  // one blob. Otherwise, it will load string from file when requested.
   71.25 -
   71.26 -#define MAX_SYMBOL_LEN  256
   71.27 -
   71.28  class ElfStringTable: CHeapObj {
   71.29    friend class ElfFile;
   71.30   public:
   71.31 @@ -48,10 +45,10 @@
   71.32    int index() { return m_index; };
   71.33  
   71.34    // get string at specified offset
   71.35 -  const char* string_at(int offset);
   71.36 +  bool string_at(int offset, char* buf, int buflen);
   71.37  
   71.38    // get status code
   71.39 -  Decoder::decoder_status get_status() { return m_status; };
   71.40 +  NullDecoder::decoder_status get_status() { return m_status; };
   71.41  
   71.42   protected:
   71.43    ElfStringTable*        m_next;
   71.44 @@ -69,13 +66,10 @@
   71.45    // section header
   71.46    Elf_Shdr                 m_shdr;
   71.47  
   71.48 -  // buffer for reading individual string
   71.49 -  char                     m_symbol[MAX_SYMBOL_LEN];
   71.50 -
   71.51    // error code
   71.52 -  Decoder::decoder_status  m_status;
   71.53 +  NullDecoder::decoder_status  m_status;
   71.54  };
   71.55  
   71.56 -#endif // _WINDOWS
   71.57 +#endif // _WINDOWS and _APPLE
   71.58  
   71.59 -#endif // __ELF_STRING_TABLE_HPP
   71.60 +#endif // SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
    72.1 --- a/src/share/vm/utilities/elfSymbolTable.cpp	Sat Jan 21 23:02:40 2012 -0500
    72.2 +++ b/src/share/vm/utilities/elfSymbolTable.cpp	Mon Jan 23 17:45:32 2012 -0800
    72.3 @@ -34,7 +34,7 @@
    72.4    m_symbols = NULL;
    72.5    m_next = NULL;
    72.6    m_file = file;
    72.7 -  m_status = Decoder::no_error;
    72.8 +  m_status = NullDecoder::no_error;
    72.9  
   72.10    // try to load the string table
   72.11    long cur_offset = ftell(file);
   72.12 @@ -45,16 +45,16 @@
   72.13        if (fseek(file, shdr.sh_offset, SEEK_SET) ||
   72.14          fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
   72.15          fseek(file, cur_offset, SEEK_SET)) {
   72.16 -        m_status = Decoder::file_invalid;
   72.17 +        m_status = NullDecoder::file_invalid;
   72.18          os::free(m_symbols);
   72.19          m_symbols = NULL;
   72.20        }
   72.21      }
   72.22 -    if (m_status == Decoder::no_error) {
   72.23 +    if (!NullDecoder::is_error(m_status)) {
   72.24        memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
   72.25      }
   72.26    } else {
   72.27 -    m_status = Decoder::file_invalid;
   72.28 +    m_status = NullDecoder::file_invalid;
   72.29    }
   72.30  }
   72.31  
   72.32 @@ -68,13 +68,13 @@
   72.33    }
   72.34  }
   72.35  
   72.36 -Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
   72.37 +bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
   72.38    assert(stringtableIndex, "null string table index pointer");
   72.39    assert(posIndex, "null string table offset pointer");
   72.40    assert(offset, "null offset pointer");
   72.41  
   72.42 -  if (m_status != Decoder::no_error) {
   72.43 -    return m_status;
   72.44 +  if (NullDecoder::is_error(m_status)) {
   72.45 +    return false;
   72.46    }
   72.47  
   72.48    address pc = 0;
   72.49 @@ -97,8 +97,8 @@
   72.50      long cur_pos;
   72.51      if ((cur_pos = ftell(m_file)) == -1 ||
   72.52        fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
   72.53 -      m_status = Decoder::file_invalid;
   72.54 -      return m_status;
   72.55 +      m_status = NullDecoder::file_invalid;
   72.56 +      return false;
   72.57      }
   72.58  
   72.59      Elf_Sym sym;
   72.60 @@ -114,13 +114,13 @@
   72.61            }
   72.62          }
   72.63        } else {
   72.64 -        m_status = Decoder::file_invalid;
   72.65 -        return m_status;
   72.66 +        m_status = NullDecoder::file_invalid;
   72.67 +        return false;
   72.68        }
   72.69      }
   72.70      fseek(m_file, cur_pos, SEEK_SET);
   72.71    }
   72.72 -  return m_status;
   72.73 +  return true;
   72.74  }
   72.75  
   72.76  #endif // _WINDOWS
    73.1 --- a/src/share/vm/utilities/elfSymbolTable.hpp	Sat Jan 21 23:02:40 2012 -0500
    73.2 +++ b/src/share/vm/utilities/elfSymbolTable.hpp	Mon Jan 23 17:45:32 2012 -0800
    73.3 @@ -1,5 +1,5 @@
    73.4  /*
    73.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    73.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    73.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    73.8   *
    73.9   * This code is free software; you can redistribute it and/or modify it
   73.10 @@ -22,8 +22,8 @@
   73.11   *
   73.12   */
   73.13  
   73.14 -#ifndef __ELF_SYMBOL_TABLE_HPP
   73.15 -#define __ELF_SYMBOL_TABLE_HPP
   73.16 +#ifndef SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
   73.17 +#define SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
   73.18  
   73.19  #if !defined(_WINDOWS) && !defined(__APPLE__)
   73.20  
   73.21 @@ -45,9 +45,9 @@
   73.22    ~ElfSymbolTable();
   73.23  
   73.24    // search the symbol that is nearest to the specified address.
   73.25 -  Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
   73.26 +  bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
   73.27  
   73.28 -  Decoder::decoder_status get_status() { return m_status; };
   73.29 +  NullDecoder::decoder_status get_status() { return m_status; };
   73.30  
   73.31   protected:
   73.32    ElfSymbolTable*  m_next;
   73.33 @@ -62,9 +62,9 @@
   73.34    // section header
   73.35    Elf_Shdr            m_shdr;
   73.36  
   73.37 -  Decoder::decoder_status  m_status;
   73.38 +  NullDecoder::decoder_status  m_status;
   73.39  };
   73.40  
   73.41 -#endif // _WINDOWS
   73.42 +#endif // _WINDOWS and _APPLE
   73.43  
   73.44 -#endif // __ELF_SYMBOL_TABLE_HPP
   73.45 +#endif // SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
    74.1 --- a/src/share/vm/utilities/vmError.cpp	Sat Jan 21 23:02:40 2012 -0500
    74.2 +++ b/src/share/vm/utilities/vmError.cpp	Mon Jan 23 17:45:32 2012 -0800
    74.3 @@ -571,8 +571,6 @@
    74.4         if (fr.pc()) {
    74.5            st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
    74.6  
    74.7 -          // initialize decoder to decode C frames
    74.8 -          Decoder decoder;
    74.9  
   74.10            int count = 0;
   74.11            while (count++ < StackPrintLimit) {
    75.1 --- a/test/compiler/7116216/StackOverflow.java	Sat Jan 21 23:02:40 2012 -0500
    75.2 +++ b/test/compiler/7116216/StackOverflow.java	Mon Jan 23 17:45:32 2012 -0800
    75.3 @@ -30,7 +30,7 @@
    75.4   * @run main/othervm -Xcomp -Xbatch StackOverflow
    75.5   */
    75.6  
    75.7 -class StackOverflow {
    75.8 +public class StackOverflow {
    75.9      static String stackOverflow_largeFrame_liveOopForGC;
   75.10  
   75.11      public static int stackOverflow_largeFrame(int call_count, String liveOopForGC) {

mercurial