Mon, 23 Jan 2012 17:45:32 -0800
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(¬_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, ®nd); 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 ®nd, bool can_change_regs ); 43.15 int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd );
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) {