This commit is contained in:
Yuri Nesterenko 2009-06-16 00:37:39 -07:00
commit d184c2ebce
489 changed files with 64249 additions and 54389 deletions

View File

@ -31,3 +31,7 @@ d52186ee770dac57950536cd00ccbfdef360b04c jdk7-b53
15096652c4d48dfb9fc0b2cb135304db94c65ba0 jdk7-b54
c8b275d62d6b0a980c510e839b70292245863e85 jdk7-b55
a8134c4ee2cf451cf9b5e1609f39d83ecd53acc5 jdk7-b56
b44f05654c26fcd1f995e712992f9b07ffd7c0c6 jdk7-b57
d60a9ce3c3eabf28f5d50ae839d18be04a551bc2 jdk7-b58
c33e7d38c9210741dbc285507403a4b20bd802a0 jdk7-b59
5a10e4d0b14d7beac53a7b2213ae6864afe1fd3e jdk7-b60

View File

@ -31,3 +31,7 @@ c235f4a8559d196879c56af80159f67ee5d0e720 jdk7-b53
2ef382b1bbd58a68e668391c6145a4b2066c5b96 jdk7-b54
aea0ace7a1e43619800931d42bbf69c579361c2d jdk7-b55
ba12117a5e6c918578d6b2a8c693232a33289024 jdk7-b56
ffd09e767dfa6d21466183a400f72cf62d53297f jdk7-b57
59b497130f82ec809c245ffb5e521e3a5fabf8af jdk7-b58
030142474602b4a067662fffc0c8e541de5a78df jdk7-b59
39565502682c7085369bd09e51640919dc741097 jdk7-b60

View File

@ -31,3 +31,7 @@ bec82237d694f9802b820fa11bbb4f7fa9bf8e77 jdk7-b52
8130ac858d6789d5853d23044ba4a992afda574a jdk7-b54
7a869f16ba83060c34b77620406cfa89d1cd7084 jdk7-b55
553a664b807bb3a3c93f3b5a3c20ff0a90e08371 jdk7-b56
972c6157fae57850694675da82fd58a17930db0a jdk7-b57
2e3b8edab3ef55406494d3dd562e06882e6fc15e jdk7-b58
7e6b2b55c00cc523b468272353ada3979adbbf16 jdk7-b59
f1e1cccbd13aa96d2d8bd872782ff764010bc22c jdk7-b60

View File

@ -1,14 +0,0 @@
README:
This file should be located at the top of the corba Mercurial repository.
See http://openjdk.java.net/ for more information about the OpenJDK.
See ../README-builds.html for complete details on build machine requirements.
Simple Build Instructions:
cd make && gnumake
The files that will be imported into the jdk build will be in the "dist"
directory.

View File

@ -46,6 +46,8 @@ CORBA_JMK_DIRECTORY=$(TOPDIR)/make/com/sun/corba/minclude/
include $(CORBA_JMK_DIRECTORY)com_sun_corba_se_PortableActivationIDL.jmk
include $(CORBA_JMK_DIRECTORY)com_sun_corba_se_impl_logging.jmk
FILES_java += com/sun/corba/se/org/omg/CORBA/ORB.java
#
# Dirs
#

View File

@ -73,23 +73,18 @@ ifeq ($(PLATFORM), linux)
ifneq ("$(findstring sparc,$(ARCH))", "")
# sparc or sparcv9
REQUIRED_CC_VER = 4.0
REQUIRED_GCC_VER = 4.0.*
else
ifeq ($(ARCH_DATA_MODEL), 32)
# i586
REQUIRED_CC_VER = 3.2
REQUIRED_GCC_VER = 3.2.1*
REQUIRED_GCC_VER_INT = 3.2.1-7a
else
ifeq ($(ARCH), amd64)
# amd64
REQUIRED_CC_VER = 3.2
REQUIRED_GCC_VER = 3.2.*
endif
ifeq ($(ARCH), ia64)
# ia64
REQUIRED_CC_VER = 3.2
REQUIRED_GCC_VER = 2.9[56789].*
endif
endif
endif
@ -109,13 +104,6 @@ ifeq ($(PLATFORM), solaris)
# Option used to create a shared library
SHARED_LIBRARY_FLAG = -G
# But gcc is still needed no matter what on 32bit
ifeq ($(ARCH_DATA_MODEL), 32)
REQUIRED_GCC_VER = 2.95
GCC =$(GCC_COMPILER_PATH)gcc
_GCC_VER :=$(shell $(GCC) -dumpversion 2>&1 )
GCC_VER :=$(call GetVersion,"$(_GCC_VER)")
endif
endif

View File

@ -39,13 +39,6 @@ ifeq ($(PLATFORM), solaris)
LINT = $(COMPILER_PATH)lint
# Option used to create a shared library
SHARED_LIBRARY_FLAG = -G
# But gcc is still needed no matter what on 32bit
ifeq ($(ARCH_DATA_MODEL), 32)
REQUIRED_GCC_VER = 2.95
GCC =$(GCC_COMPILER_PATH)gcc
_GCC_VER :=$(shell $(GCC) -dumpversion 2>&1 )
GCC_VER :=$(call GetVersion,"$(_GCC_VER)")
endif
endif
# Sun Studio Compiler settings specific to Linux

View File

@ -288,11 +288,22 @@ ifeq ($(PLATFORM), windows)
TEMP_DISK=C:/temp
# GNU Make or MKS overrides $(PROCESSOR_ARCHITECTURE) to always
# return "x86". Use the first word of $(PROCESSOR_IDENTIFIER) instead.
PROC_ARCH:=$(word 1, $(PROCESSOR_IDENTIFIER))
PROC_ARCH:=$(subst x86,X86,$(PROC_ARCH))
PROC_ARCH:=$(subst x64,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst intel64,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst Intel64,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst INTEL64,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst em64t,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst EM64T,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst amd64,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst AMD64,X64,$(PROC_ARCH))
PROC_ARCH:=$(subst ia64,IA64,$(PROC_ARCH))
ifndef ARCH_DATA_MODEL
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64)
ifeq ($(PROC_ARCH),IA64)
ARCH_DATA_MODEL=64
else
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),AMD64)
ifeq ($(PROC_ARCH),X64)
ARCH_DATA_MODEL=64
else
ARCH_DATA_MODEL=32
@ -313,10 +324,12 @@ ifeq ($(PLATFORM), windows)
# + set ARCH to ia64 or amd64, or
REQUIRED_WINDOWS_NAME=Windows Server 2003
REQUIRED_WINDOWS_VERSION=5 2 Service Pack 1
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)), AMD64)
ifeq ($(PROC_ARCH),X64)
ARCH=amd64
else
ARCH=ia64
ifeq ($(PROC_ARCH),IA64)
ARCH=ia64
endif
endif
LIBARCH=$(ARCH)
# Value of Java os.arch property

View File

@ -202,6 +202,10 @@ public class IDLNameTranslatorImpl implements IDLNameTranslator {
private IDLNameTranslatorImpl(Class[] interfaces)
{
SecurityManager s = System.getSecurityManager();
if (s != null) {
s.checkPermission(new DynamicAccessPermission("access"));
}
try {
IDLTypesUtil idlTypesUtil = new IDLTypesUtil();
for (int ctr=0; ctr<interfaces.length; ctr++)

View File

@ -1,11 +1,35 @@
/*
* Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* COMPONENT_NAME: idl.parser
*
*
* ORIGINS: 27
*
* THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM
* 5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
*
*
*/
CORBA IDL

View File

@ -1,11 +1,35 @@
/*
* Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* COMPONENT_NAME: idl.parser
*
*
* ORIGINS: 27
*
* THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM
* 5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
*
*
*/
CORBA IDL

View File

@ -1,14 +1,38 @@
/*
* COMPONENT_NAME: idl.parser
*
* ORIGINS: 27
* Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM
* 5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
CORBA 2.3 IDL
/*
* COMPONENT_NAME: idl.parser
*
* ORIGINS: 27
*
* 5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
*
*/
CORBA 2.3 IDL
---------------
(1) <specification> <definition><specification'>
@ -83,7 +107,7 @@ CORBA 2.3 IDL
(16) <vad> e
<export> <vad>
(17) <value_dcl> <value_header> "{" <value_element> <ve> "}"
(17) <ve> e
@ -91,9 +115,9 @@ CORBA 2.3 IDL
(18) <value_header> "custom" "valuetype" <id> <value_inheritance_spec>
"valuetype" <id> <value_inheritance_spec>
"custom" "valuetype" <id>
"valuetype" <id>
"custom" "valuetype" <id>
"valuetype" <id>
(19) <value_inheritance_spec> <opt_inherits> <opt_supports>
(19) <opt_inherits> e
@ -107,7 +131,7 @@ CORBA 2.3 IDL
"supports" <interface_name> <interface_name_list>
(19) <interface_name_list> e
"," <interface_name> <interface_name_list>
"," <interface_name> <interface_name_list>
(20) <value_name> <scoped_name>
@ -121,7 +145,7 @@ CORBA 2.3 IDL
(23) <init_dcl> "factory" <id> "(" ")"
"factory" <id> "(" <init_param_dcls> ")"
(24) <init_param_dcls> <init_param_decl>
(24) <init_param_dcls> <init_param_decl>
<init_param_decl> "," <init_param_dcls>
(25) <init_param_dcl> <init_param_attribute> <param_type_spec> <simple_declarator>
@ -349,7 +373,7 @@ CORBA 2.3 IDL
(87) <op_dcl''> e
<context_expr>
<raises_expr>
<raises_expr>
<raises_expr> <context_expr>
(88) <op_attribute> "oneway"
@ -386,7 +410,7 @@ CORBA 2.3 IDL
<wide_string_type>
<scoped_name>
(96) <fixed_pt_type> "fixed" "<" <positive_int_const> "," <positive_int_const> ">"
(96) <fixed_pt_type> "fixed" "<" <positive_int_const> "," <positive_int_const> ">"
(97) <fixed_pt_const_type> "fixed"

View File

@ -1,11 +1,35 @@
/*
* Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* COMPONENT_NAME: idl.parser
*
*
* ORIGINS: 27
*
* THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM
* 5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
*
*
*/
(1) <specification> <imports> <definition> <specification'> // CORBA3
@ -98,7 +122,7 @@
(16) <vad> e
<export> <vad>
(17) <value_dcl> <value_header> "{" <value_element> <ve> "}"
(17) <ve> e
@ -106,9 +130,9 @@
(18) <value_header> "custom" "valuetype" <id> <value_inheritance_spec>
"valuetype" <id> <value_inheritance_spec>
"custom" "valuetype" <id>
"valuetype" <id>
"custom" "valuetype" <id>
"valuetype" <id>
(19) <value_inheritance_spec> <opt_inherits> <opt_supports>
(19) <opt_inherits> e
@ -122,7 +146,7 @@
"supports" <interface_name> <interface_name_list>
(19) <interface_name_list> e
"," <interface_name> <interface_name_list>
"," <interface_name> <interface_name_list>
(20) <value_name> <scoped_name>
@ -136,7 +160,7 @@
(23) <init_dcl> "factory" <id> "(" ")"
"factory" <id> "(" <init_param_dcls> ")"
(24) <init_param_dcls> <init_param_dcl>
(24) <init_param_dcls> <init_param_dcl>
<init_param_dcl> "," <init_param_dcls>
(25) <init_param_dcl> <init_param_attribute> <param_type_spec> <simple_declarator>
@ -351,7 +375,7 @@
(85) <readonly_attr_spec> <readonly_attr_header> <readonly_attr_declarator> // CORBA3
(85) <readonly_attr_header> "readonly" "attribute" <param_type_spec> // CORBA3
(85) <readonly_attr_declarator> <simple_declarator> <get_excep_expr> // CORBA3
<simple_declarator> <sds> // CORBA3
@ -389,7 +413,7 @@
(87) <op_dcl''> e
<context_expr>
<raises_expr>
<raises_expr>
<raises_expr> <context_expr>
(88) <op_attribute> "oneway"
@ -426,7 +450,7 @@
<wide_string_type>
<scoped_name>
(96) <fixed_pt_type> "fixed" "<" <positive_int_const> "," <positive_int_const> ">"
(96) <fixed_pt_type> "fixed" "<" <positive_int_const> "," <positive_int_const> ">"
(97) <fixed_pt_const_type> "fixed"
@ -450,7 +474,7 @@
(204) <snames> e
"," <scoped_name> <snames>
(205) <component_inheritance_spec> ":" <scoped_name>
(206) <component_body> <component_export> <ces>
@ -458,8 +482,8 @@
(206) <ces> e
<component_export> <ces>
(207) <component_export> <provides_dcl> ";"
<uses_dcl> ";"
(207) <component_export> <provides_dcl> ";"
<uses_dcl> ";"
<emits_dcl> ";"
<publishes_dcl> ";"
<consumes_dcl> ";"

View File

@ -1,3 +1,28 @@
#
# Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# COMPONENT_NAME: idl.parser
#

View File

@ -1,3 +1,28 @@
#
# Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# COMPONENT_NAME: idl.parser
#

View File

@ -1,3 +1,28 @@
#
# Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# COMPONENT_NAME: idl.parser
#

View File

@ -1,3 +1,28 @@
#
# Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# COMPONENT_NAME: idl.toJava
#

View File

@ -1,3 +1,28 @@
#
# Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# COMPONENT_NAME: idl.toJava
#

View File

@ -1,3 +1,28 @@
#
# Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# COMPONENT_NAME: idl.toJava
#

View File

@ -31,3 +31,7 @@ dae503d9f04c1a11e182dbf7f770509c28dc0609 jdk7-b50
fafab5d5349c7c066d677538db67a1ee0fb33bd2 jdk7-b54
f8e839c086152da70d6ec5913ba6f9f509282e8d jdk7-b55
a3fd9e40ff2e854f6169eb6d09d491a28634d04f jdk7-b56
f4cbf78110c726919f46b59a3b054c54c7e889b4 jdk7-b57
53d9bf689e80fcc76b221bbe6c5d58e08b80cbc6 jdk7-b58
c55be0c7bd32c016c52218eb4c8b5da8a75450b5 jdk7-b59
a77eddcd510c3972717c025cfcef9a60bfa4ecac jdk7-b60

View File

@ -60,6 +60,14 @@ ifndef LDNOMAP
LFLAGS_LIBSA = -Xlinker --version-script=mapfile
endif
# If this is a --hash-style=gnu system, use --hash-style=both
# The gnu .hash section won't work on some Linux systems like SuSE 10.
_HAS_HASH_STYLE_GNU:=$(shell $(CC) -dumpspecs | grep -- '--hash-style=gnu')
ifneq ($(_HAS_HASH_STYLE_GNU),)
LDFLAGS_HASH_STYLE = -Wl,--hash-style=both
endif
LFLAGS_LIBSA += $(LDFLAGS_HASH_STYLE)
$(LIBSA): $(OBJS) mapfile
if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi
$(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)

View File

@ -306,8 +306,6 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride);
} while (nameAddr != null);
String symbol = "heapOopSize"; // global int constant and value is initialized at runtime.
addIntConstant(symbol, (int)lookupInProcess(symbol).getCIntegerAt(0, 4, false));
}
private void readVMLongConstants() {

View File

@ -317,11 +317,11 @@ public class JavaThread extends Thread {
}
public Address getStackBase() {
return stackBaseField.getValue();
return stackBaseField.getValue(addr);
}
public long getStackSize() {
return stackSizeField.getValue();
return stackSizeField.getValue(addr);
}
/** Gets the Java-side thread object for this JavaThread */

View File

@ -318,11 +318,17 @@ public class VM {
logMinObjAlignmentInBytes = db.lookupIntConstant("LogMinObjAlignmentInBytes").intValue();
heapWordSize = db.lookupIntConstant("HeapWordSize").intValue();
oopSize = db.lookupIntConstant("oopSize").intValue();
heapOopSize = db.lookupIntConstant("heapOopSize").intValue();
intxType = db.lookupType("intx");
uintxType = db.lookupType("uintx");
boolType = (CIntegerType) db.lookupType("bool");
if (isCompressedOopsEnabled()) {
// Size info for oops within java objects is fixed
heapOopSize = (int)getIntSize();
} else {
heapOopSize = (int)getOopSize();
}
}
/** This could be used by a reflective runtime system */
@ -343,13 +349,12 @@ public class VM {
}
soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
debugger.putHeapConst(soleInstance.getHeapOopSize(), Universe.getNarrowOopBase(),
Universe.getNarrowOopShift());
for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
((Observer) iter.next()).update(null, null);
}
debugger.putHeapConst(soleInstance.getHeapOopSize(), Universe.getNarrowOopBase(),
Universe.getNarrowOopShift());
}
/** This is used by the debugging system */

View File

@ -1,14 +0,0 @@
README:
This file should be located at the top of the hotspot Mercurial repository.
See http://openjdk.java.net/ for more information about the OpenJDK.
See ../README-builds.html for complete details on build machine requirements.
Simple Build Instructions:
cd make && gnumake
The files that will be imported into the jdk build will be in the "build"
directory.

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2009
HS_MAJOR_VER=16
HS_MINOR_VER=0
HS_BUILD_NUMBER=02
HS_BUILD_NUMBER=04
JDK_MAJOR_VER=1
JDK_MINOR_VER=7

View File

@ -1,275 +0,0 @@
#!echo "This is not a shell script"
#
# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
#############################################################################
# Error
error() # message
{
echo "ERROR: $1"
exit 6
}
# Directory must exist
dirMustExist() # dir name
{
if [ ! -d "$1" ] ; then
error "Directory for $2 does not exist: $1"
fi
}
# File must exist
fileMustExist() # dir name
{
if [ ! -f "$1" ] ; then
error "File for $2 does not exist: $1"
fi
}
#############################################################################
# Should be set by JPRT as the 3 basic inputs
bootdir="${ALT_BOOTDIR}"
slashjava="${ALT_SLASH_JAVA}"
jdk_import="${ALT_JDK_IMPORT_PATH}"
# Check input
dirMustExist "${bootdir}" ALT_BOOTDIR
dirMustExist "${slashjava}" ALT_SLASH_JAVA
dirMustExist "${jdk_import}" ALT_JDK_IMPORT_PATH
# Uses 'uname -s', but only expect SunOS or Linux, assume Windows otherwise.
osname=`uname -s`
if [ "${osname}" = SunOS ] ; then
# SOLARIS: Sparc or X86
osarch=`uname -p`
if [ "${osarch}" = sparc ] ; then
solaris_arch=sparc
else
solaris_arch=i386
fi
if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
else
if [ "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6" -o \
"${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6u10" -o \
"${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6u14" -o \
"${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6perf" ] ; then
# All jdk6 builds use SS11
compiler_name=SS11
else
compiler_name=SS12
fi
fi
# Get into path (make sure it matches ALT setting)
compiler_path=${slashjava}/devtools/${solaris_arch}/SUNWspro/${compiler_name}/bin
dirMustExist "${compiler_path}" COMPILER_PATH
path4sdk=${compiler_path}
# Add basic solaris system paths
path4sdk=${path4sdk}:/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
# Get the previous JDK to be used to bootstrap the build
path4sdk=${bootdir}/bin:${path4sdk}
# Find GNU make
make=/usr/sfw/bin/gmake
if [ ! -f ${make} ] ; then
make=/opt/sfw/bin/gmake
if [ ! -f ${make} ] ; then
make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
fi
fi
fileMustExist "${make}" make
# File creation mask
umask 002
elif [ "${osname}" = Linux ] ; then
# LINUX: X86, AMD64
osarch=`uname -m`
if [ "${osarch}" = i686 ] ; then
linux_arch=i586
elif [ "${osarch}" = x86_64 ] ; then
linux_arch=amd64
fi
# Get the compilers into path (make sure it matches ALT setting)
compiler_path=/usr/bin
dirMustExist "${compiler_path}" COMPILER_PATH
path4sdk=${compiler_path}
# Add basic paths
path4sdk=${path4sdk}:/usr/bin:/bin:/usr/sbin:/sbin
# Get the previous JDK to be used to bootstrap the build
path4sdk=${bootdir}/bin:${path4sdk}
# Find GNU make
make=/usr/bin/make
fileMustExist "${make}" make
umask 002
else
# Windows: Differs on CYGWIN vs. MKS, and the compiler available.
# Also, blanks in pathnames gives GNU make headaches, so anything placed
# in any ALT_* variable should be the short windows dosname.
# WINDOWS: Install and use MKS or CYGWIN (should have already been done)
# Assumption here is that you are in a shell window via MKS or cygwin.
# MKS install should have defined the environment variable ROOTDIR.
# We also need to figure out which one we have: X86, AMD64
if [ "`echo ${PROCESSOR_IDENTIFIER} | fgrep AMD64`" != "" ] ; then
windows_arch=amd64
else
windows_arch=i586
fi
# We need to determine if we are running a CYGWIN shell or an MKS shell
# (if uname isn't available, then it will be unix_toolset=unknown)
unix_toolset=unknown
if [ "`uname -a | fgrep Cygwin`" = "" -a -d "${ROOTDIR}" ] ; then
# We kind of assume ROOTDIR is where MKS is and it's ok
unix_toolset=MKS
mkshome=`dosname -s "${ROOTDIR}"`
# Utility to convert to short pathnames without spaces
dosname="${mkshome}/mksnt/dosname -s"
# Most unix utilities are in the mksnt directory of ROOTDIR
unixcommand_path="${mkshome}/mksnt"
path4sdk="${unixcommand_path}"
dirMustExist "${unixcommand_path}" UNIXCOMMAND_PATH
devtools_path="${slashjava}/devtools/win32/bin"
path4sdk="${devtools_path};${path4sdk}"
dirMustExist "${devtools_path}" DEVTOOLS_PATH
# Find GNU make
make="${devtools_path}/gnumake.exe"
fileMustExist "${make}" make
elif [ "`uname -a | fgrep Cygwin`" != "" -a -f /bin/cygpath ] ; then
# For CYGWIN, uname will have "Cygwin" in it, and /bin/cygpath should exist
unix_toolset=CYGWIN
# Utility to convert to short pathnames without spaces
dosname="/usr/bin/cygpath -a -m -s"
# Most unix utilities are in the /usr/bin
unixcommand_path="/usr/bin"
path4sdk="${unixcommand_path}"
dirMustExist "${unixcommand_path}" UNIXCOMMAND_PATH
# Find GNU make
make="${unixcommand_path}/make.exe"
fileMustExist "${make}" make
else
echo "WARNING: Cannot figure out if this is MKS or CYGWIN"
fi
# WINDOWS: Compiler setup (nasty part)
# NOTE: You can use vcvars32.bat to set PATH, LIB, and INCLUDE.
# NOTE: CYGWIN has a link.exe too, make sure the compilers are first
if [ "${windows_arch}" = i586 ] ; then
# 32bit Windows compiler settings
# VisualStudio .NET 2003 VC++ 7.1 (VS71COMNTOOLS should be defined)
vs_root=`${dosname} "${VS71COMNTOOLS}/../.."`
# Fill in PATH, LIB, and INCLUDE (unset all others to make sure)
vc7_root="${vs_root}/Vc7"
compiler_path="${vc7_root}/bin"
platform_sdk="${vc7_root}/PlatformSDK"
# LIB and INCLUDE must use ; as a separator
include4sdk="${vc7_root}/atlmfc/include"
include4sdk="${include4sdk};${vc7_root}/include"
include4sdk="${include4sdk};${platform_sdk}/include/prerelease"
include4sdk="${include4sdk};${platform_sdk}/include"
include4sdk="${include4sdk};${vs_root}/SDK/v1.1/include"
lib4sdk="${vc7_root}/atlmfc/lib"
lib4sdk="${lib4sdk};${vc7_root}/lib"
lib4sdk="${lib4sdk};${platform_sdk}/lib/prerelease"
lib4sdk="${lib4sdk};${platform_sdk}/lib"
lib4sdk="${lib4sdk};${vs_root}/SDK/v1.1/lib"
# Search path and DLL locating path
# WARNING: CYGWIN has a link.exe too, make sure compilers are first
path4sdk="${vs_root}/Common7/Tools/bin;${path4sdk}"
path4sdk="${vs_root}/SDK/v1.1/bin;${path4sdk}"
path4sdk="${vs_root}/Common7/Tools;${path4sdk}"
path4sdk="${vs_root}/Common7/Tools/bin/prerelease;${path4sdk}"
path4sdk="${vs_root}/Common7/IDE;${path4sdk}"
path4sdk="${compiler_path};${path4sdk}"
elif [ "${windows_arch}" = amd64 ] ; then
# AMD64 64bit Windows compiler settings
if [ "${MSSDK}" != "" ] ; then
platform_sdk="${MSSDK}"
else
platform_sdk=`${dosname} "C:/Program Files/Microsoft Platform SDK/"`
fi
compiler_path="${platform_sdk}/Bin/win64/x86/AMD64"
# LIB and INCLUDE must use ; as a separator
include4sdk="${platform_sdk}/Include"
include4sdk="${include4sdk};${platform_sdk}/Include/crt/sys"
include4sdk="${include4sdk};${platform_sdk}/Include/mfc"
include4sdk="${include4sdk};${platform_sdk}/Include/atl"
include4sdk="${include4sdk};${platform_sdk}/Include/crt"
lib4sdk="${platform_sdk}/Lib/AMD64"
lib4sdk="${lib4sdk};${platform_sdk}/Lib/AMD64/atlmfc"
# Search path and DLL locating path
# WARNING: CYGWIN has a link.exe too, make sure compilers are first
path4sdk="${platform_sdk}/bin;${path4sdk}"
path4sdk="${compiler_path};${path4sdk}"
fi
# Export LIB and INCLUDE
unset lib
unset Lib
LIB="${lib4sdk}"
export LIB
unset include
unset Include
INCLUDE="${include4sdk}"
export INCLUDE
# Set the ALT variable
dirMustExist "${compiler_path}" COMPILER_PATH
# WINDOWS: Get the previous JDK to be used to bootstrap the build
path4sdk="${bootdir}/bin;${path4sdk}"
# Turn all \\ into /, remove duplicates and trailing /
slash_path="`echo ${path4sdk} | sed -e 's@\\\\@/@g' -e 's@//@/@g' -e 's@/$@@' -e 's@/;@;@g'`"
# For windows, it's hard to know where the system is, so we just add this
# to PATH.
path4sdk="${slash_path};${PATH}"
# Convert path4sdk to cygwin style
if [ "${unix_toolset}" = CYGWIN ] ; then
path4sdk="`/usr/bin/cygpath -p ${path4sdk}`"
fi
fi
# Export PATH setting
PATH="${path4sdk}"
export PATH
# Unset certain vars
unset LD_LIBRARY_PATH
unset LD_LIBRARY_PATH_32
unset LD_LIBRARY_PATH_64

View File

@ -70,10 +70,33 @@ jprt.my.solaris.x64.jdk6u10=solaris_x64_5.10
jprt.my.solaris.x64.jdk6u14=solaris_x64_5.10
jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
jprt.my.linux.i586=linux_i586
jprt.my.linux.x64=linux_x64
jprt.my.windows.i586=windows_i586
jprt.my.windows.x64=windows_x64
jprt.my.linux.i586.jdk7=linux_i586_2.6
jprt.my.linux.i586.jdk6=linux_i586_2.4
jprt.my.linux.i586.jdk6perf=linux_i586_2.4
jprt.my.linux.i586.jdk6u10=linux_i586_2.4
jprt.my.linux.i586.jdk6u14=linux_i586_2.4
jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
jprt.my.linux.x64.jdk7=linux_x64_2.6
jprt.my.linux.x64.jdk6=linux_x64_2.4
jprt.my.linux.x64.jdk6perf=linux_x64_2.4
jprt.my.linux.x64.jdk6u10=linux_x64_2.4
jprt.my.linux.x64.jdk6u14=linux_x64_2.4
jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
jprt.my.windows.i586.jdk7=windows_i586_5.0
jprt.my.windows.i586.jdk6=windows_i586_5.0
jprt.my.windows.i586.jdk6perf=windows_i586_5.0
jprt.my.windows.i586.jdk6u10=windows_i586_5.0
jprt.my.windows.i586.jdk6u14=windows_i586_5.0
jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
jprt.my.windows.x64.jdk7=windows_x64_5.2
jprt.my.windows.x64.jdk6=windows_x64_5.2
jprt.my.windows.x64.jdk6perf=windows_x64_5.2
jprt.my.windows.x64.jdk6u10=windows_x64_5.2
jprt.my.windows.x64.jdk6u14=windows_x64_5.2
jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
# Standard list of jprt build targets for this source tree
@ -312,7 +335,19 @@ jprt.test.targets = \
# The default test/Makefile targets that should be run
# Example:
# jprt.make.rule.test.targets=*-*-*-packtest
#jprt.make.rule.test.targets=*-product-*-packtest
jprt.make.rule.test.targets = \
${jprt.my.solaris.sparc}-*-c1-clienttest, \
${jprt.my.solaris.i586}-*-c1-clienttest, \
${jprt.my.linux.i586}-*-c1-clienttest, \
${jprt.my.windows.i586}-*-c1-clienttest, \
${jprt.my.solaris.sparc}-*-c2-servertest, \
${jprt.my.solaris.sparcv9}-*-c2-servertest, \
${jprt.my.solaris.i586}-*-c2-servertest, \
${jprt.my.solaris.x64}-*-c2-servertest, \
${jprt.my.linux.i586}-*-c2-servertest, \
${jprt.my.linux.x64}-*-c2-servertest, \
${jprt.my.windows.i586}-*-c2-servertest, \
${jprt.my.windows.x64}-*-c2-servertest

View File

@ -113,6 +113,11 @@ endif
OPT_CFLAGS/NOOPT=-O0
# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
ifneq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) = 3 \) \))" "0"
OPT_CFLAGS/mulnode.o += -O0
endif
#------------------------------------------------------------------------
# Linker flags
@ -166,3 +171,9 @@ DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
DEBUG_CFLAGS += -gstabs
endif
# DEBUG_BINARIES overrides everything, use full -g debug information
ifeq ($(DEBUG_BINARIES), true)
DEBUG_CFLAGS = -g
CFLAGS += $(DEBUG_CFLAGS)
endif

View File

@ -39,12 +39,17 @@ LIBJSIG_MAPFILE = $(MAKEFILES_DIR)/mapfile-vers-jsig
# cause problems with interposing. See CR: 6466665
# LFLAGS_JSIG += $(MAPFLAG:FILENAME=$(LIBJSIG_MAPFILE))
LFLAGS_JSIG += -D_GNU_SOURCE -D_REENTRANT
LFLAGS_JSIG += -D_GNU_SOURCE -D_REENTRANT $(LDFLAGS_HASH_STYLE)
# DEBUG_BINARIES overrides everything, use full -g debug information
ifeq ($(DEBUG_BINARIES), true)
JSIG_DEBUG_CFLAGS = -g
endif
$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
@echo Making signal interposition lib...
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
$(LFLAGS_JSIG) -o $@ $< -ldl
$(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
install_jsig: $(LIBJSIG)
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"

View File

@ -43,6 +43,11 @@ SAMAPFILE = $(SASRCDIR)/mapfile
DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC)
# DEBUG_BINARIES overrides everything, use full -g debug information
ifeq ($(DEBUG_BINARIES), true)
SA_DEBUG_CFLAGS = -g
endif
# if $(AGENT_DIR) does not exist, we don't build SA
# also, we don't build SA on Itanium.
@ -51,7 +56,7 @@ checkAndBuildSA:
$(MAKE) -f vm.make $(LIBSAPROC); \
fi
SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE))
SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE)) $(LDFLAGS_HASH_STYLE)
$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
@ -67,6 +72,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
-I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \
$(SASRCFILES) \
$(SA_LFLAGS) \
$(SA_DEBUG_CFLAGS) \
-o $@ \
-lthread_db

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4454,43 +4454,26 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val
delayed()->nop();
}
// Now we decide how to generate the card table write. If we're
// enqueueing, we call out to a generated function. Otherwise, we do it
// inline here.
if (G1RSBarrierUseQueue) {
// If the "store_addr" register is an "in" or "local" register, move it to
// a scratch reg so we can pass it as an argument.
bool use_scr = !(store_addr->is_global() || store_addr->is_out());
// Pick a scratch register different from "tmp".
Register scr = (tmp == G1_scratch ? G3_scratch : G1_scratch);
// Make sure we use up the delay slot!
if (use_scr) {
post_filter_masm->mov(store_addr, scr);
} else {
post_filter_masm->nop();
}
generate_dirty_card_log_enqueue_if_necessary(bs->byte_map_base);
save_frame(0);
call(dirty_card_log_enqueue);
if (use_scr) {
delayed()->mov(scr, O0);
} else {
delayed()->mov(store_addr->after_save(), O0);
}
restore();
// If the "store_addr" register is an "in" or "local" register, move it to
// a scratch reg so we can pass it as an argument.
bool use_scr = !(store_addr->is_global() || store_addr->is_out());
// Pick a scratch register different from "tmp".
Register scr = (tmp == G1_scratch ? G3_scratch : G1_scratch);
// Make sure we use up the delay slot!
if (use_scr) {
post_filter_masm->mov(store_addr, scr);
} else {
#ifdef _LP64
post_filter_masm->srlx(store_addr, CardTableModRefBS::card_shift, store_addr);
#else
post_filter_masm->srl(store_addr, CardTableModRefBS::card_shift, store_addr);
#endif
assert(tmp != store_addr, "need separate temp reg");
set(bs->byte_map_base, tmp);
stb(G0, tmp, store_addr);
post_filter_masm->nop();
}
generate_dirty_card_log_enqueue_if_necessary(bs->byte_map_base);
save_frame(0);
call(dirty_card_log_enqueue);
if (use_scr) {
delayed()->mov(scr, O0);
} else {
delayed()->mov(store_addr->after_save(), O0);
}
restore();
bind(filtered);

View File

@ -378,7 +378,7 @@ void LIR_Assembler::emit_exception_handler() {
compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
__ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
__ delayed()->nop();
}

View File

@ -286,7 +286,7 @@ void C1_MacroAssembler::initialize_object(
initialize_body(base, index);
}
if (DTraceAllocProbes) {
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == O0, "must be");
call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
relocInfo::runtime_call_type);
@ -355,7 +355,7 @@ void C1_MacroAssembler::allocate_array(
sub(arr_size, hdr_size * wordSize, index); // compute index = number of words to clear
initialize_body(base, index);
if (DTraceAllocProbes) {
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == O0, "must be");
call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
relocInfo::runtime_call_type);

View File

@ -59,7 +59,7 @@ inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL &&
inline bool frame::is_older(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
return this->id() > id ; }
inline int frame::frame_size() const { return sender_sp() - sp(); }
inline int frame::frame_size(RegisterMap* map) const { return sender_sp() - sp(); }
inline intptr_t* frame::link() const { return (intptr_t *)(fp()[FP->sp_offset_in_saved_window()] + STACK_BIAS); }

View File

@ -1712,6 +1712,23 @@ static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) {
return as_DoubleFloatRegister(register_encoding);
}
const bool Matcher::match_rule_supported(int opcode) {
if (!has_match_rule(opcode))
return false;
switch (opcode) {
case Op_CountLeadingZerosI:
case Op_CountLeadingZerosL:
case Op_CountTrailingZerosI:
case Op_CountTrailingZerosL:
if (!UsePopCountInstruction)
return false;
break;
}
return true; // Per default match rules are supported.
}
int Matcher::regnum_to_fpu_offset(int regnum) {
return regnum - 32; // The FP registers are in the second chunk
}
@ -1874,15 +1891,17 @@ RegMask Matcher::modL_proj_mask() {
// The intptr_t operand types, defined by textual substitution.
// (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.)
#ifdef _LP64
#define immX immL
#define immX13 immL13
#define iRegX iRegL
#define g1RegX g1RegL
#define immX immL
#define immX13 immL13
#define immX13m7 immL13m7
#define iRegX iRegL
#define g1RegX g1RegL
#else
#define immX immI
#define immX13 immI13
#define iRegX iRegI
#define g1RegX g1RegI
#define immX immI
#define immX13 immI13
#define immX13m7 immI13m7
#define iRegX iRegI
#define g1RegX g1RegI
#endif
//----------ENCODING BLOCK-----------------------------------------------------
@ -3437,6 +3456,16 @@ operand immI13() %{
interface(CONST_INTER);
%}
// Integer Immediate: 13-bit minus 7
operand immI13m7() %{
predicate((-4096 < n->get_int()) && ((n->get_int() + 7) <= 4095));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Unsigned (positive) Integer Immediate: 13-bit
operand immU13() %{
predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int()));
@ -3515,6 +3544,28 @@ operand immI_32_63() %{
interface(CONST_INTER);
%}
// Immediates for special shifts (sign extend)
// Integer Immediate: the value 16
operand immI_16() %{
predicate(n->get_int() == 16);
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Integer Immediate: the value 24
operand immI_24() %{
predicate(n->get_int() == 24);
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Integer Immediate: the value 255
operand immI_255() %{
predicate( n->get_int() == 255 );
@ -3525,6 +3576,16 @@ operand immI_255() %{
interface(CONST_INTER);
%}
// Integer Immediate: the value 65535
operand immI_65535() %{
predicate(n->get_int() == 65535);
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Long Immediate: the value FF
operand immL_FF() %{
predicate( n->get_long() == 0xFFL );
@ -3630,6 +3691,16 @@ operand immL13() %{
interface(CONST_INTER);
%}
// Long Immediate: 13-bit minus 7
operand immL13m7() %{
predicate((-4096L < n->get_long()) && ((n->get_long() + 7L) <= 4095L));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Long Immediate: low 32-bit mask
operand immL_32bits() %{
predicate(n->get_long() == 0xFFFFFFFFL);
@ -4067,7 +4138,7 @@ operand indirect(sp_ptr_RegP reg) %{
%}
%}
// Indirect with Offset
// Indirect with simm13 Offset
operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
@ -4082,6 +4153,21 @@ operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{
%}
%}
// Indirect with simm13 Offset minus 7
operand indOffset13m7(sp_ptr_RegP reg, immX13m7 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
index(0x0);
scale(0x0);
disp($offset);
%}
%}
// Note: Intel has a swapped version also, like this:
//operand indOffsetX(iRegI reg, immP offset) %{
// constraint(ALLOC_IN_RC(int_reg));
@ -5487,6 +5573,20 @@ instruct loadS(iRegI dst, memory mem) %{
ins_pipe(iload_mask_mem);
%}
// Load Short (16 bit signed) to Byte (8 bit signed)
instruct loadS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDSB $mem+1,$dst\t! short -> byte" %}
ins_encode %{
__ ldsb($mem$$Address, $dst$$Register, 1);
%}
ins_pipe(iload_mask_mem);
%}
// Load Short (16bit signed) into a Long Register
instruct loadS2L(iRegL dst, memory mem) %{
match(Set dst (ConvI2L (LoadS mem)));
@ -5513,6 +5613,19 @@ instruct loadUS(iRegI dst, memory mem) %{
ins_pipe(iload_mask_mem);
%}
// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
instruct loadUS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDSB $mem+1,$dst\t! ushort -> byte" %}
ins_encode %{
__ ldsb($mem$$Address, $dst$$Register, 1);
%}
ins_pipe(iload_mask_mem);
%}
// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
instruct loadUS2L(iRegL dst, memory mem) %{
match(Set dst (ConvI2L (LoadUS mem)));
@ -5539,6 +5652,62 @@ instruct loadI(iRegI dst, memory mem) %{
ins_pipe(iload_mem);
%}
// Load Integer to Byte (8 bit signed)
instruct loadI2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDSB $mem+3,$dst\t! int -> byte" %}
ins_encode %{
__ ldsb($mem$$Address, $dst$$Register, 3);
%}
ins_pipe(iload_mask_mem);
%}
// Load Integer to Unsigned Byte (8 bit UNsigned)
instruct loadI2UB(iRegI dst, indOffset13m7 mem, immI_255 mask) %{
match(Set dst (AndI (LoadI mem) mask));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUB $mem+3,$dst\t! int -> ubyte" %}
ins_encode %{
__ ldub($mem$$Address, $dst$$Register, 3);
%}
ins_pipe(iload_mask_mem);
%}
// Load Integer to Short (16 bit signed)
instruct loadI2S(iRegI dst, indOffset13m7 mem, immI_16 sixteen) %{
match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDSH $mem+2,$dst\t! int -> short" %}
ins_encode %{
__ ldsh($mem$$Address, $dst$$Register, 2);
%}
ins_pipe(iload_mask_mem);
%}
// Load Integer to Unsigned Short (16 bit UNsigned)
instruct loadI2US(iRegI dst, indOffset13m7 mem, immI_65535 mask) %{
match(Set dst (AndI (LoadI mem) mask));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUH $mem+2,$dst\t! int -> ushort/char" %}
ins_encode %{
__ lduh($mem$$Address, $dst$$Register, 2);
%}
ins_pipe(iload_mask_mem);
%}
// Load Integer into a Long Register
instruct loadI2L(iRegL dst, memory mem) %{
match(Set dst (ConvI2L (LoadI mem)));
@ -9188,6 +9357,145 @@ instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp
ins_pipe(long_memory_op);
%}
//---------- Zeros Count Instructions ------------------------------------------
instruct countLeadingZerosI(iRegI dst, iRegI src, iRegI tmp, flagsReg cr) %{
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
match(Set dst (CountLeadingZerosI src));
effect(TEMP dst, TEMP tmp, KILL cr);
// x |= (x >> 1);
// x |= (x >> 2);
// x |= (x >> 4);
// x |= (x >> 8);
// x |= (x >> 16);
// return (WORDBITS - popc(x));
format %{ "SRL $src,1,$dst\t! count leading zeros (int)\n\t"
"OR $src,$tmp,$dst\n\t"
"SRL $dst,2,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRL $dst,4,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRL $dst,8,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRL $dst,16,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"POPC $dst,$dst\n\t"
"MOV 32,$tmp\n\t"
"SUB $tmp,$dst,$dst" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Register Rtmp = $tmp$$Register;
__ srl(Rsrc, 1, Rtmp);
__ or3(Rsrc, Rtmp, Rdst);
__ srl(Rdst, 2, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srl(Rdst, 4, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srl(Rdst, 8, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srl(Rdst, 16, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ popc(Rdst, Rdst);
__ mov(BitsPerInt, Rtmp);
__ sub(Rtmp, Rdst, Rdst);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosL(iRegI dst, iRegL src, iRegL tmp, flagsReg cr) %{
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
match(Set dst (CountLeadingZerosL src));
effect(TEMP dst, TEMP tmp, KILL cr);
// x |= (x >> 1);
// x |= (x >> 2);
// x |= (x >> 4);
// x |= (x >> 8);
// x |= (x >> 16);
// x |= (x >> 32);
// return (WORDBITS - popc(x));
format %{ "SRLX $src,1,$dst\t! count leading zeros (long)\n\t"
"OR $src,$tmp,$dst\n\t"
"SRLX $dst,2,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRLX $dst,4,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRLX $dst,8,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRLX $dst,16,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRLX $dst,32,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"POPC $dst,$dst\n\t"
"MOV 64,$tmp\n\t"
"SUB $tmp,$dst,$dst" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Register Rtmp = $tmp$$Register;
__ srlx(Rsrc, 1, Rtmp);
__ or3(Rsrc, Rtmp, Rdst);
__ srlx(Rdst, 2, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srlx(Rdst, 4, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srlx(Rdst, 8, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srlx(Rdst, 16, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srlx(Rdst, 32, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ popc(Rdst, Rdst);
__ mov(BitsPerLong, Rtmp);
__ sub(Rtmp, Rdst, Rdst);
%}
ins_pipe(ialu_reg);
%}
instruct countTrailingZerosI(iRegI dst, iRegI src, flagsReg cr) %{
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
match(Set dst (CountTrailingZerosI src));
effect(TEMP dst, KILL cr);
// return popc(~x & (x - 1));
format %{ "SUB $src,1,$dst\t! count trailing zeros (int)\n\t"
"ANDN $dst,$src,$dst\n\t"
"SRL $dst,R_G0,$dst\n\t"
"POPC $dst,$dst" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
__ sub(Rsrc, 1, Rdst);
__ andn(Rdst, Rsrc, Rdst);
__ srl(Rdst, G0, Rdst);
__ popc(Rdst, Rdst);
%}
ins_pipe(ialu_reg);
%}
instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
match(Set dst (CountTrailingZerosL src));
effect(TEMP dst, KILL cr);
// return popc(~x & (x - 1));
format %{ "SUB $src,1,$dst\t! count trailing zeros (long)\n\t"
"ANDN $dst,$src,$dst\n\t"
"POPC $dst,$dst" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
__ sub(Rsrc, 1, Rdst);
__ andn(Rdst, Rsrc, Rdst);
__ popc(Rdst, Rdst);
%}
ins_pipe(ialu_reg);
%}
//---------- Population Count Instructions -------------------------------------
instruct popCountI(iRegI dst, iRegI src) %{

View File

@ -952,6 +952,21 @@ void Assembler::andpd(XMMRegister dst, Address src) {
emit_operand(dst, src);
}
void Assembler::bsfl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
emit_byte(0x0F);
emit_byte(0xBC);
emit_byte(0xC0 | encode);
}
void Assembler::bsrl(Register dst, Register src) {
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
int encode = prefix_and_encode(dst->encoding(), src->encoding());
emit_byte(0x0F);
emit_byte(0xBD);
emit_byte(0xC0 | encode);
}
void Assembler::bswapl(Register reg) { // bswap
int encode = prefix_and_encode(reg->encoding());
emit_byte(0x0F);
@ -1438,6 +1453,15 @@ void Assembler::lock() {
}
}
void Assembler::lzcntl(Register dst, Register src) {
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
emit_byte(0xF3);
int encode = prefix_and_encode(dst->encoding(), src->encoding());
emit_byte(0x0F);
emit_byte(0xBD);
emit_byte(0xC0 | encode);
}
// Emit mfence instruction
void Assembler::mfence() {
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
@ -3688,6 +3712,21 @@ void Assembler::andq(Register dst, Register src) {
emit_arith(0x23, 0xC0, dst, src);
}
void Assembler::bsfq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
emit_byte(0x0F);
emit_byte(0xBC);
emit_byte(0xC0 | encode);
}
void Assembler::bsrq(Register dst, Register src) {
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
emit_byte(0x0F);
emit_byte(0xBD);
emit_byte(0xC0 | encode);
}
void Assembler::bswapq(Register reg) {
int encode = prefixq_and_encode(reg->encoding());
emit_byte(0x0F);
@ -3941,6 +3980,15 @@ void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder con
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::lzcntq(Register dst, Register src) {
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
emit_byte(0xF3);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
emit_byte(0x0F);
emit_byte(0xBD);
emit_byte(0xC0 | encode);
}
void Assembler::movdq(XMMRegister dst, Register src) {
// table D-1 says MMX/SSE2
NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), ""));

View File

@ -757,6 +757,14 @@ private:
void andpd(XMMRegister dst, Address src);
void andpd(XMMRegister dst, XMMRegister src);
void bsfl(Register dst, Register src);
void bsrl(Register dst, Register src);
#ifdef _LP64
void bsfq(Register dst, Register src);
void bsrq(Register dst, Register src);
#endif
void bswapl(Register reg);
void bswapq(Register reg);
@ -1061,6 +1069,12 @@ private:
void lock();
void lzcntl(Register dst, Register src);
#ifdef _LP64
void lzcntq(Register dst, Register src);
#endif
enum Membar_mask_bits {
StoreStore = 1 << 3,
LoadStore = 1 << 2,

View File

@ -439,7 +439,7 @@ void LIR_Assembler::emit_exception_handler() {
// if the method does not have an exception handler, then there is
// no reason to search for one
if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
// the exception oop and pc are in rax, and rdx
// no other registers need to be preserved, so invalidate them
__ invalidate_registers(false, true, true, false, true, true);

View File

@ -258,7 +258,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register
}
}
if (DTraceAllocProbes) {
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == rax, "must be");
call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
}
@ -291,7 +291,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
const Register len_zero = len;
initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
if (DTraceAllocProbes) {
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == rax, "must be");
call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
}

View File

@ -237,9 +237,8 @@ bool frame::is_interpreted_frame() const {
return Interpreter::contains(pc());
}
int frame::frame_size() const {
RegisterMap map(JavaThread::current(), false);
frame sender = this->sender(&map);
int frame::frame_size(RegisterMap* map) const {
frame sender = this->sender(map);
return sender.sp() - sp();
}

View File

@ -284,7 +284,7 @@ void VM_Version::get_processor_features() {
}
char buf[256];
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
cores_per_cpu(), threads_per_core(),
cpu_family(), _model, _stepping,
(supports_cmov() ? ", cmov" : ""),
@ -301,6 +301,7 @@ void VM_Version::get_processor_features() {
(supports_mmx_ext() ? ", mmxext" : ""),
(supports_3dnow() ? ", 3dnow" : ""),
(supports_3dnow2() ? ", 3dnowext" : ""),
(supports_lzcnt() ? ", lzcnt": ""),
(supports_sse4a() ? ", sse4a": ""),
(supports_ht() ? ", ht": ""));
_features_str = strdup(buf);
@ -364,6 +365,13 @@ void VM_Version::get_processor_features() {
UseXmmI2D = false;
}
}
// Use count leading zeros count instruction if available.
if (supports_lzcnt()) {
if (FLAG_IS_DEFAULT(UseCountLeadingZerosInstruction)) {
UseCountLeadingZerosInstruction = true;
}
}
}
if( is_intel() ) { // Intel cpus specific settings

View File

@ -120,7 +120,7 @@ public:
uint32_t LahfSahf : 1,
CmpLegacy : 1,
: 4,
abm : 1,
lzcnt : 1,
sse4a : 1,
misalignsse : 1,
prefetchw : 1,
@ -182,7 +182,8 @@ protected:
CPU_SSE4A = (1 << 10),
CPU_SSE4_1 = (1 << 11),
CPU_SSE4_2 = (1 << 12),
CPU_POPCNT = (1 << 13)
CPU_POPCNT = (1 << 13),
CPU_LZCNT = (1 << 14)
} cpuFeatureFlags;
// cpuid information block. All info derived from executing cpuid with
@ -277,8 +278,6 @@ protected:
if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || is_amd() &&
_cpuid_info.ext_cpuid1_edx.bits.mmx != 0)
result |= CPU_MMX;
if (is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
result |= CPU_3DNOW;
if (_cpuid_info.std_cpuid1_edx.bits.sse != 0)
result |= CPU_SSE;
if (_cpuid_info.std_cpuid1_edx.bits.sse2 != 0)
@ -287,14 +286,23 @@ protected:
result |= CPU_SSE3;
if (_cpuid_info.std_cpuid1_ecx.bits.ssse3 != 0)
result |= CPU_SSSE3;
if (is_amd() && _cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
result |= CPU_SSE4A;
if (_cpuid_info.std_cpuid1_ecx.bits.sse4_1 != 0)
result |= CPU_SSE4_1;
if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
result |= CPU_SSE4_2;
if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
result |= CPU_POPCNT;
// AMD features.
if (is_amd()) {
if (_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
result |= CPU_3DNOW;
if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
result |= CPU_LZCNT;
if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
result |= CPU_SSE4A;
}
return result;
}
@ -391,6 +399,7 @@ public:
static bool supports_3dnow() { return (_cpuFeatures & CPU_3DNOW) != 0; }
static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
static bool supports_3dnow2() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow2 != 0; }
static bool supports_lzcnt() { return (_cpuFeatures & CPU_LZCNT) != 0; }
static bool supports_sse4a() { return (_cpuFeatures & CPU_SSE4A) != 0; }
static bool supports_compare_and_exchange() { return true; }

View File

@ -1281,6 +1281,13 @@ static void emit_float_constant(CodeBuffer& cbuf, float x) {
}
const bool Matcher::match_rule_supported(int opcode) {
if (!has_match_rule(opcode))
return false;
return true; // Per default match rules are supported.
}
int Matcher::regnum_to_fpu_offset(int regnum) {
return regnum - 32; // The FP registers are in the second chunk
}
@ -5233,6 +5240,15 @@ operand immI_255() %{
interface(CONST_INTER);
%}
// Constant for short-wide masking
operand immI_65535() %{
predicate(n->get_int() == 65535);
match(ConI);
format %{ %}
interface(CONST_INTER);
%}
// Register Operands
// Integer Register
operand eRegI() %{
@ -6644,6 +6660,153 @@ instruct bytes_reverse_long(eRegL dst) %{
%}
//---------- Zeros Count Instructions ------------------------------------------
instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
predicate(UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosI src));
effect(KILL cr);
format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %}
ins_encode %{
__ lzcntl($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eFlagsReg cr) %{
predicate(!UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosI src));
effect(KILL cr);
format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t"
"JNZ skip\n\t"
"MOV $dst, -1\n"
"skip:\n\t"
"NEG $dst\n\t"
"ADD $dst, 31" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Label skip;
__ bsrl(Rdst, Rsrc);
__ jccb(Assembler::notZero, skip);
__ movl(Rdst, -1);
__ bind(skip);
__ negl(Rdst);
__ addl(Rdst, BitsPerInt - 1);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
predicate(UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosL src));
effect(TEMP dst, KILL cr);
format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t"
"JNC done\n\t"
"LZCNT $dst, $src.lo\n\t"
"ADD $dst, 32\n"
"done:" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Label done;
__ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
__ jccb(Assembler::carryClear, done);
__ lzcntl(Rdst, Rsrc);
__ addl(Rdst, BitsPerInt);
__ bind(done);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eFlagsReg cr) %{
predicate(!UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosL src));
effect(TEMP dst, KILL cr);
format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t"
"JZ msw_is_zero\n\t"
"ADD $dst, 32\n\t"
"JMP not_zero\n"
"msw_is_zero:\n\t"
"BSR $dst, $src.lo\n\t"
"JNZ not_zero\n\t"
"MOV $dst, -1\n"
"not_zero:\n\t"
"NEG $dst\n\t"
"ADD $dst, 63\n" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Label msw_is_zero;
Label not_zero;
__ bsrl(Rdst, HIGH_FROM_LOW(Rsrc));
__ jccb(Assembler::zero, msw_is_zero);
__ addl(Rdst, BitsPerInt);
__ jmpb(not_zero);
__ bind(msw_is_zero);
__ bsrl(Rdst, Rsrc);
__ jccb(Assembler::notZero, not_zero);
__ movl(Rdst, -1);
__ bind(not_zero);
__ negl(Rdst);
__ addl(Rdst, BitsPerLong - 1);
%}
ins_pipe(ialu_reg);
%}
instruct countTrailingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
match(Set dst (CountTrailingZerosI src));
effect(KILL cr);
format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t"
"JNZ done\n\t"
"MOV $dst, 32\n"
"done:" %}
ins_encode %{
Register Rdst = $dst$$Register;
Label done;
__ bsfl(Rdst, $src$$Register);
__ jccb(Assembler::notZero, done);
__ movl(Rdst, BitsPerInt);
__ bind(done);
%}
ins_pipe(ialu_reg);
%}
instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
match(Set dst (CountTrailingZerosL src));
effect(TEMP dst, KILL cr);
format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t"
"JNZ done\n\t"
"BSF $dst, $src.hi\n\t"
"JNZ msw_not_zero\n\t"
"MOV $dst, 32\n"
"msw_not_zero:\n\t"
"ADD $dst, 32\n"
"done:" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Label msw_not_zero;
Label done;
__ bsfl(Rdst, Rsrc);
__ jccb(Assembler::notZero, done);
__ bsfl(Rdst, HIGH_FROM_LOW(Rsrc));
__ jccb(Assembler::notZero, msw_not_zero);
__ movl(Rdst, BitsPerInt);
__ bind(msw_not_zero);
__ addl(Rdst, BitsPerInt);
__ bind(done);
%}
ins_pipe(ialu_reg);
%}
//---------- Population Count Instructions -------------------------------------
instruct popCountI(eRegI dst, eRegI src) %{
@ -6784,6 +6947,18 @@ instruct loadS(eRegI dst, memory mem) %{
ins_pipe(ialu_reg_mem);
%}
// Load Short (16 bit signed) to Byte (8 bit signed)
instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
ins_cost(125);
format %{ "MOVSX $dst, $mem\t# short -> byte" %}
ins_encode %{
__ movsbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Short (16bit signed) into Long Register
instruct loadS2L(eRegL dst, memory mem) %{
match(Set dst (ConvI2L (LoadS mem)));
@ -6816,9 +6991,20 @@ instruct loadUS(eRegI dst, memory mem) %{
ins_pipe(ialu_reg_mem);
%}
// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
ins_cost(125);
format %{ "MOVSX $dst, $mem\t# ushort -> byte" %}
ins_encode %{
__ movsbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
instruct loadUS2L(eRegL dst, memory mem)
%{
instruct loadUS2L(eRegL dst, memory mem) %{
match(Set dst (ConvI2L (LoadUS mem)));
ins_cost(250);
@ -6847,6 +7033,54 @@ instruct loadI(eRegI dst, memory mem) %{
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Byte (8 bit signed)
instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
ins_cost(125);
format %{ "MOVSX $dst, $mem\t# int -> byte" %}
ins_encode %{
__ movsbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{
match(Set dst (AndI (LoadI mem) mask));
ins_cost(125);
format %{ "MOVZX $dst, $mem\t# int -> ubyte" %}
ins_encode %{
__ movzbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Short (16 bit signed)
instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{
match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
ins_cost(125);
format %{ "MOVSX $dst, $mem\t# int -> short" %}
ins_encode %{
__ movswl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{
match(Set dst (AndI (LoadI mem) mask));
ins_cost(125);
format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %}
ins_encode %{
__ movzwl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer into Long Register
instruct loadI2L(eRegL dst, memory mem) %{
match(Set dst (ConvI2L (LoadI mem)));
@ -8880,28 +9114,28 @@ instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
// This idiom is used by the compiler for the i2b bytecode.
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
effect(KILL cr);
size(3);
format %{ "MOVSX $dst,$src :8" %}
opcode(0xBE, 0x0F);
ins_encode( OpcS, OpcP, RegReg( dst, src));
ins_pipe( ialu_reg_reg );
ins_encode %{
__ movsbl($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
// This idiom is used by the compiler the i2s bytecode.
instruct i2s(eRegI dst, xRegI src, immI_16 sixteen, eFlagsReg cr) %{
instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{
match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
effect(KILL cr);
size(3);
format %{ "MOVSX $dst,$src :16" %}
opcode(0xBF, 0x0F);
ins_encode( OpcS, OpcP, RegReg( dst, src));
ins_pipe( ialu_reg_reg );
ins_encode %{
__ movswl($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg_reg);
%}

View File

@ -1980,6 +1980,13 @@ static void emit_float_constant(CodeBuffer& cbuf, float x) {
}
const bool Matcher::match_rule_supported(int opcode) {
if (!has_match_rule(opcode))
return false;
return true; // Per default match rules are supported.
}
int Matcher::regnum_to_fpu_offset(int regnum)
{
return regnum - 32; // The FP registers are in the second chunk
@ -6452,6 +6459,18 @@ instruct loadS(rRegI dst, memory mem)
ins_pipe(ialu_reg_mem);
%}
// Load Short (16 bit signed) to Byte (8 bit signed)
instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
ins_cost(125);
format %{ "movsbl $dst, $mem\t# short -> byte" %}
ins_encode %{
__ movsbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Short (16 bit signed) into Long Register
instruct loadS2L(rRegL dst, memory mem)
%{
@ -6482,6 +6501,18 @@ instruct loadUS(rRegI dst, memory mem)
ins_pipe(ialu_reg_mem);
%}
// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
ins_cost(125);
format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
ins_encode %{
__ movsbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
instruct loadUS2L(rRegL dst, memory mem)
%{
@ -6512,6 +6543,54 @@ instruct loadI(rRegI dst, memory mem)
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Byte (8 bit signed)
instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
ins_cost(125);
format %{ "movsbl $dst, $mem\t# int -> byte" %}
ins_encode %{
__ movsbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
match(Set dst (AndI (LoadI mem) mask));
ins_cost(125);
format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
ins_encode %{
__ movzbl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Short (16 bit signed)
instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
ins_cost(125);
format %{ "movswl $dst, $mem\t# int -> short" %}
ins_encode %{
__ movswl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
match(Set dst (AndI (LoadI mem) mask));
ins_cost(125);
format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
ins_encode %{
__ movzwl($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem);
%}
// Load Integer into Long Register
instruct loadI2L(rRegL dst, memory mem)
%{
@ -7656,6 +7735,121 @@ instruct storeL_reversed(memory dst, rRegL src) %{
%}
//---------- Zeros Count Instructions ------------------------------------------
instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
predicate(UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosI src));
effect(KILL cr);
format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
ins_encode %{
__ lzcntl($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
predicate(!UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosI src));
effect(KILL cr);
format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
"jnz skip\n\t"
"movl $dst, -1\n"
"skip:\n\t"
"negl $dst\n\t"
"addl $dst, 31" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Label skip;
__ bsrl(Rdst, Rsrc);
__ jccb(Assembler::notZero, skip);
__ movl(Rdst, -1);
__ bind(skip);
__ negl(Rdst);
__ addl(Rdst, BitsPerInt - 1);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
predicate(UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosL src));
effect(KILL cr);
format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
ins_encode %{
__ lzcntq($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
predicate(!UseCountLeadingZerosInstruction);
match(Set dst (CountLeadingZerosL src));
effect(KILL cr);
format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
"jnz skip\n\t"
"movl $dst, -1\n"
"skip:\n\t"
"negl $dst\n\t"
"addl $dst, 63" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rsrc = $src$$Register;
Label skip;
__ bsrq(Rdst, Rsrc);
__ jccb(Assembler::notZero, skip);
__ movl(Rdst, -1);
__ bind(skip);
__ negl(Rdst);
__ addl(Rdst, BitsPerLong - 1);
%}
ins_pipe(ialu_reg);
%}
instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
match(Set dst (CountTrailingZerosI src));
effect(KILL cr);
format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
"jnz done\n\t"
"movl $dst, 32\n"
"done:" %}
ins_encode %{
Register Rdst = $dst$$Register;
Label done;
__ bsfl(Rdst, $src$$Register);
__ jccb(Assembler::notZero, done);
__ movl(Rdst, BitsPerInt);
__ bind(done);
%}
ins_pipe(ialu_reg);
%}
instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
match(Set dst (CountTrailingZerosL src));
effect(KILL cr);
format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
"jnz done\n\t"
"movl $dst, 64\n"
"done:" %}
ins_encode %{
Register Rdst = $dst$$Register;
Label done;
__ bsfq(Rdst, $src$$Register);
__ jccb(Assembler::notZero, done);
__ movl(Rdst, BitsPerLong);
__ bind(done);
%}
ins_pipe(ialu_reg);
%}
//---------- Population Count Instructions -------------------------------------
instruct popCountI(rRegI dst, rRegI src) %{

View File

@ -2314,7 +2314,8 @@ bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
void os::free_memory(char *addr, size_t bytes) {
uncommit_memory(addr, bytes);
::mmap(addr, bytes, PROT_READ | PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
}
void os::numa_make_global(char *addr, size_t bytes) {
@ -2361,6 +2362,19 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info
extern "C" void numa_warn(int number, char *where, ...) { }
extern "C" void numa_error(char *where) { }
// If we are running with libnuma version > 2, then we should
// be trying to use symbols with versions 1.1
// If we are running with earlier version, which did not have symbol versions,
// we should use the base version.
void* os::Linux::libnuma_dlsym(void* handle, const char *name) {
void *f = dlvsym(handle, name, "libnuma_1.1");
if (f == NULL) {
f = dlsym(handle, name);
}
return f;
}
bool os::Linux::libnuma_init() {
// sched_getcpu() should be in libc.
set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
@ -2370,19 +2384,19 @@ bool os::Linux::libnuma_init() {
void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
if (handle != NULL) {
set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t,
dlsym(handle, "numa_node_to_cpus")));
libnuma_dlsym(handle, "numa_node_to_cpus")));
set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t,
dlsym(handle, "numa_max_node")));
libnuma_dlsym(handle, "numa_max_node")));
set_numa_available(CAST_TO_FN_PTR(numa_available_func_t,
dlsym(handle, "numa_available")));
libnuma_dlsym(handle, "numa_available")));
set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
dlsym(handle, "numa_tonode_memory")));
libnuma_dlsym(handle, "numa_tonode_memory")));
set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
dlsym(handle, "numa_interleave_memory")));
libnuma_dlsym(handle, "numa_interleave_memory")));
if (numa_available() != -1) {
set_numa_all_nodes((unsigned long*)dlsym(handle, "numa_all_nodes"));
set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
// Create a cpu -> node mapping
_cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
rebuild_cpu_to_node_map();

View File

@ -147,7 +147,7 @@ class Linux {
static void libpthread_init();
static bool libnuma_init();
static void* libnuma_dlsym(void* handle, const char* name);
// Minimum stack size a thread can be created with (allowing
// the VM to completely create the thread and enter user code)
static size_t min_stack_allowed;

View File

@ -73,7 +73,7 @@ class FileBuff {
// This converts a pointer into the buffer to a file offset. It only works
// when the pointer is valid (i.e. just obtained from getline()).
long getoff(const char* s) { return _bufoff + (s - _buf); }
long getoff(const char* s) { return _bufoff + (long)(s - _buf); }
};
//------------------------------FileBuffRegion---------------------------------

View File

@ -1745,6 +1745,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
fprintf(fp," del_req(i);\n");
fprintf(fp," }\n");
fprintf(fp," _num_opnds = %d;\n", new_num_opnds);
assert(new_num_opnds == node->num_unique_opnds(), "what?");
}
}
@ -3761,6 +3762,12 @@ bool InstructForm::define_cisc_version(ArchDesc &AD, FILE *fp_cpp) {
if ( this->captures_bottom_type() ) {
fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
}
uint cur_num_opnds = num_opnds();
if (cur_num_opnds > 1 && cur_num_opnds != num_unique_opnds()) {
fprintf(fp_cpp," node->_num_opnds = %d;\n", num_unique_opnds());
}
fprintf(fp_cpp, "\n");
fprintf(fp_cpp, " // Copy _idx, inputs and operands to new node\n");
fprintf(fp_cpp, " fill_new_machnode(node, C);\n");

View File

@ -319,7 +319,7 @@ void Compilation::compile_method() {
return;
}
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
if (_env->jvmti_can_hotswap_or_post_breakpoint()) {
// We can assert evol_method because method->can_be_compiled is true.
dependency_recorder()->assert_evol_method(method());
}
@ -435,7 +435,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time");
_arena = Thread::current()->resource_area();
_compilation = this;
_needs_debug_information = JvmtiExport::can_examine_or_deopt_anywhere() ||
_needs_debug_information = _env->jvmti_can_examine_or_deopt_anywhere() ||
JavaMonitorsInStackTrace || AlwaysEmitDebugInfo || DeoptimizeALot;
_exception_info_list = new ExceptionInfoList();
_implicit_exception_table.set_size(0);

View File

@ -1662,7 +1662,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
// Register dependence if JVMTI has either breakpoint
// setting or hotswapping of methods capabilities since they may
// cause deoptimization.
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
dependency_recorder()->assert_evol_method(inline_target);
}
return;
@ -2863,7 +2863,7 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
start_block->merge(_initial_state);
BlockBegin* sync_handler = NULL;
if (method()->is_synchronized() || DTraceMethodProbes) {
if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) {
// setup an exception handler to do the unlocking and/or notification
sync_handler = new BlockBegin(-1);
sync_handler->set(BlockBegin::exception_entry_flag);

View File

@ -1064,7 +1064,7 @@ void LIRGenerator::do_IfInstanceOf(IfInstanceOf* x) {
void LIRGenerator::do_Return(Return* x) {
if (DTraceMethodProbes) {
if (compilation()->env()->dtrace_method_probes()) {
BasicTypeList signature;
signature.append(T_INT); // thread
signature.append(T_OBJECT); // methodOop
@ -1769,7 +1769,7 @@ void LIRGenerator::do_Throw(Throw* x) {
__ null_check(exception_opr, new CodeEmitInfo(info, true));
}
if (JvmtiExport::can_post_exceptions() &&
if (compilation()->env()->jvmti_can_post_exceptions() &&
!block()->is_set(BlockBegin::default_exception_handler_flag)) {
// we need to go through the exception lookup path to get JVMTI
// notification done
@ -1779,7 +1779,7 @@ void LIRGenerator::do_Throw(Throw* x) {
assert(!block()->is_set(BlockBegin::default_exception_handler_flag) || unwind,
"should be no more handlers to dispatch to");
if (DTraceMethodProbes &&
if (compilation()->env()->dtrace_method_probes() &&
block()->is_set(BlockBegin::default_exception_handler_flag)) {
// notify that this frame is unwinding
BasicTypeList signature;
@ -2204,7 +2204,7 @@ void LIRGenerator::do_Base(Base* x) {
java_index += type2size[t];
}
if (DTraceMethodProbes) {
if (compilation()->env()->dtrace_method_probes()) {
BasicTypeList signature;
signature.append(T_INT); // thread
signature.append(T_OBJECT); // methodOop

View File

@ -170,6 +170,34 @@ ciEnv::~ciEnv() {
current_thread->set_env(NULL);
}
// ------------------------------------------------------------------
// Cache Jvmti state
void ciEnv::cache_jvmti_state() {
VM_ENTRY_MARK;
// Get Jvmti capabilities under lock to get consistant values.
MutexLocker mu(JvmtiThreadState_lock);
_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
_jvmti_can_examine_or_deopt_anywhere = JvmtiExport::can_examine_or_deopt_anywhere();
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();
_jvmti_can_post_exceptions = JvmtiExport::can_post_exceptions();
}
// ------------------------------------------------------------------
// Cache DTrace flags
void ciEnv::cache_dtrace_flags() {
// Need lock?
_dtrace_extended_probes = ExtendedDTraceProbes;
if (_dtrace_extended_probes) {
_dtrace_monitor_probes = true;
_dtrace_method_probes = true;
_dtrace_alloc_probes = true;
} else {
_dtrace_monitor_probes = DTraceMonitorProbes;
_dtrace_method_probes = DTraceMethodProbes;
_dtrace_alloc_probes = DTraceAllocProbes;
}
}
// ------------------------------------------------------------------
// helper for lazy exception creation
ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) {
@ -810,16 +838,39 @@ void ciEnv::register_method(ciMethod* target,
// and invalidating our dependencies until we install this method.
MutexLocker ml(Compile_lock);
if (log() != NULL) {
// Log the dependencies which this compilation declares.
dependencies()->log_all_dependencies();
// Change in Jvmti state may invalidate compilation.
if (!failing() &&
( (!jvmti_can_hotswap_or_post_breakpoint() &&
JvmtiExport::can_hotswap_or_post_breakpoint()) ||
(!jvmti_can_examine_or_deopt_anywhere() &&
JvmtiExport::can_examine_or_deopt_anywhere()) ||
(!jvmti_can_access_local_variables() &&
JvmtiExport::can_access_local_variables()) ||
(!jvmti_can_post_exceptions() &&
JvmtiExport::can_post_exceptions()) )) {
record_failure("Jvmti state change invalidated dependencies");
}
// Encode the dependencies now, so we can check them right away.
dependencies()->encode_content_bytes();
// Change in DTrace flags may invalidate compilation.
if (!failing() &&
( (!dtrace_extended_probes() && ExtendedDTraceProbes) ||
(!dtrace_method_probes() && DTraceMethodProbes) ||
(!dtrace_alloc_probes() && DTraceAllocProbes) )) {
record_failure("DTrace flags change invalidated dependencies");
}
// Check for {class loads, evolution, breakpoints} during compilation
check_for_system_dictionary_modification(target);
if (!failing()) {
if (log() != NULL) {
// Log the dependencies which this compilation declares.
dependencies()->log_all_dependencies();
}
// Encode the dependencies now, so we can check them right away.
dependencies()->encode_content_bytes();
// Check for {class loads, evolution, breakpoints} during compilation
check_for_system_dictionary_modification(target);
}
methodHandle method(THREAD, target->get_methodOop());

View File

@ -53,6 +53,18 @@ private:
char* _name_buffer;
int _name_buffer_len;
// Cache Jvmti state
bool _jvmti_can_hotswap_or_post_breakpoint;
bool _jvmti_can_examine_or_deopt_anywhere;
bool _jvmti_can_access_local_variables;
bool _jvmti_can_post_exceptions;
// Cache DTrace flags
bool _dtrace_extended_probes;
bool _dtrace_monitor_probes;
bool _dtrace_method_probes;
bool _dtrace_alloc_probes;
// Distinguished instances of certain ciObjects..
static ciObject* _null_object_instance;
static ciMethodKlass* _method_klass_instance;
@ -236,6 +248,20 @@ public:
bool break_at_compile() { return _break_at_compile; }
void set_break_at_compile(bool z) { _break_at_compile = z; }
// Cache Jvmti state
void cache_jvmti_state();
bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; }
bool jvmti_can_examine_or_deopt_anywhere() const { return _jvmti_can_examine_or_deopt_anywhere; }
bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; }
bool jvmti_can_post_exceptions() const { return _jvmti_can_post_exceptions; }
// Cache DTrace flags
void cache_dtrace_flags();
bool dtrace_extended_probes() const { return _dtrace_extended_probes; }
bool dtrace_monitor_probes() const { return _dtrace_monitor_probes; }
bool dtrace_method_probes() const { return _dtrace_method_probes; }
bool dtrace_alloc_probes() const { return _dtrace_alloc_probes; }
// The compiler task which has created this env.
// May be useful to find out compile_id, comp_level, etc.
CompileTask* task() { return _task; }

View File

@ -60,7 +60,8 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
_flow = NULL;
#endif // COMPILER2
if (JvmtiExport::can_hotswap_or_post_breakpoint() && _is_compilable) {
ciEnv *env = CURRENT_ENV;
if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) {
// 6328518 check hotswap conditions under the right lock.
MutexLocker locker(Compile_lock);
if (Dependencies::check_evol_method(h_m()) != NULL) {
@ -84,7 +85,6 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
if (_can_be_statically_bound && h_m()->is_abstract())
_can_be_statically_bound = false;
ciEnv *env = CURRENT_ENV;
// generating _signature may allow GC and therefore move m.
// These fields are always filled in.
_name = env->get_object(h_m()->name())->as_symbol();
@ -337,7 +337,7 @@ MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
_liveness->compute_liveness();
}
MethodLivenessResult result = _liveness->get_liveness_at(bci);
if (JvmtiExport::can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
// Keep all locals live for the user's edification and amusement.
result.at_put_range(0, result.size(), true);
}

View File

@ -313,6 +313,8 @@
template(value_name, "value") \
template(frontCacheEnabled_name, "frontCacheEnabled") \
template(stringCacheEnabled_name, "stringCacheEnabled") \
template(numberOfLeadingZeros_name, "numberOfLeadingZeros") \
template(numberOfTrailingZeros_name, "numberOfTrailingZeros") \
template(bitCount_name, "bitCount") \
template(profile_name, "profile") \
template(equals_name, "equals") \
@ -559,6 +561,12 @@
do_intrinsic(_longBitsToDouble, java_lang_Double, longBitsToDouble_name, long_double_signature, F_S) \
do_name( longBitsToDouble_name, "longBitsToDouble") \
\
do_intrinsic(_numberOfLeadingZeros_i, java_lang_Integer, numberOfLeadingZeros_name,int_int_signature, F_S) \
do_intrinsic(_numberOfLeadingZeros_l, java_lang_Long, numberOfLeadingZeros_name,long_int_signature, F_S) \
\
do_intrinsic(_numberOfTrailingZeros_i, java_lang_Integer, numberOfTrailingZeros_name,int_int_signature, F_S) \
do_intrinsic(_numberOfTrailingZeros_l, java_lang_Long, numberOfTrailingZeros_name,long_int_signature, F_S) \
\
do_intrinsic(_bitCount_i, java_lang_Integer, bitCount_name, int_int_signature, F_S) \
do_intrinsic(_bitCount_l, java_lang_Long, bitCount_name, long_int_signature, F_S) \
\

View File

@ -1530,6 +1530,12 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
assert(thread->env() == &ci_env, "set by ci_env");
// The thread-env() field is cleared in ~CompileTaskWrapper.
// Cache Jvmti state
ci_env.cache_jvmti_state();
// Cache DTrace flags
ci_env.cache_dtrace_flags();
ciMethod* target = ci_env.get_method_from_handle(target_handle);
TraceTime t1("compilation", &time);

View File

@ -555,6 +555,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_collector_policy(cp),
_should_unload_classes(false),
_concurrent_cycles_since_last_unload(0),
_roots_scanning_options(0),
_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
{
if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {

View File

@ -545,6 +545,11 @@ class CMSCollector: public CHeapObj {
bool unloaded_classes_last_cycle() const {
return concurrent_cycles_since_last_unload() == 0;
}
// Root scanning options for perm gen
int _roots_scanning_options;
int roots_scanning_options() const { return _roots_scanning_options; }
void add_root_scanning_option(int o) { _roots_scanning_options |= o; }
void remove_root_scanning_option(int o) { _roots_scanning_options &= ~o; }
// Verification support
CMSBitMap _verification_mark_bm;
@ -719,11 +724,6 @@ class CMSCollector: public CHeapObj {
NOT_PRODUCT(bool simulate_overflow();) // sequential
NOT_PRODUCT(bool par_simulate_overflow();) // MT version
int _roots_scanning_options;
int roots_scanning_options() const { return _roots_scanning_options; }
void add_root_scanning_option(int o) { _roots_scanning_options |= o; }
void remove_root_scanning_option(int o) { _roots_scanning_options &= ~o; }
// CMS work methods
void checkpointRootsInitialWork(bool asynch); // initial checkpoint work

View File

@ -25,26 +25,37 @@
#include "incls/_precompiled.incl"
#include "incls/_concurrentG1Refine.cpp.incl"
bool ConcurrentG1Refine::_enabled = false;
ConcurrentG1Refine::ConcurrentG1Refine() :
_pya(PYA_continue), _last_pya(PYA_continue),
_last_cards_during(), _first_traversal(false),
_card_counts(NULL), _cur_card_count_histo(NULL), _cum_card_count_histo(NULL),
_hot_cache(NULL),
_def_use_cache(false), _use_cache(false),
_n_periods(0), _total_cards(0), _total_travs(0)
_n_periods(0), _total_cards(0), _total_travs(0),
_threads(NULL), _n_threads(0)
{
if (G1ConcRefine) {
_cg1rThread = new ConcurrentG1RefineThread(this);
assert(cg1rThread() != NULL, "Conc refine should have been created");
assert(cg1rThread()->cg1r() == this,
"Conc refine thread should refer to this");
} else {
_cg1rThread = NULL;
_n_threads = (int)thread_num();
if (_n_threads > 0) {
_threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
ConcurrentG1RefineThread *next = NULL;
for (int i = _n_threads - 1; i >= 0; i--) {
ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
assert(t != NULL, "Conc refine should have been created");
assert(t->cg1r() == this, "Conc refine thread should refer to this");
_threads[i] = t;
next = t;
}
}
}
}
size_t ConcurrentG1Refine::thread_num() {
if (G1ConcRefine) {
return (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
}
return 0;
}
void ConcurrentG1Refine::init() {
if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
@ -75,6 +86,14 @@ void ConcurrentG1Refine::init() {
}
}
void ConcurrentG1Refine::stop() {
if (_threads != NULL) {
for (int i = 0; i < _n_threads; i++) {
_threads[i]->stop();
}
}
}
ConcurrentG1Refine::~ConcurrentG1Refine() {
if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
assert(_card_counts != NULL, "Logic");
@ -88,104 +107,22 @@ ConcurrentG1Refine::~ConcurrentG1Refine() {
assert(_hot_cache != NULL, "Logic");
FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
}
}
bool ConcurrentG1Refine::refine() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
unsigned cards_before = g1h->g1_rem_set()->conc_refine_cards();
clear_hot_cache(); // Any previous values in this are now invalid.
g1h->g1_rem_set()->concurrentRefinementPass(this);
_traversals++;
unsigned cards_after = g1h->g1_rem_set()->conc_refine_cards();
unsigned cards_during = cards_after-cards_before;
// If this is the first traversal in the current enabling
// and we did some cards, or if the number of cards found is decreasing
// sufficiently quickly, then keep going. Otherwise, sleep a while.
bool res =
(_first_traversal && cards_during > 0)
||
(!_first_traversal && cards_during * 3 < _last_cards_during * 2);
_last_cards_during = cards_during;
_first_traversal = false;
return res;
}
void ConcurrentG1Refine::enable() {
MutexLocker x(G1ConcRefine_mon);
if (!_enabled) {
_enabled = true;
_first_traversal = true; _last_cards_during = 0;
G1ConcRefine_mon->notify_all();
if (_threads != NULL) {
for (int i = 0; i < _n_threads; i++) {
delete _threads[i];
}
FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
}
}
unsigned ConcurrentG1Refine::disable() {
MutexLocker x(G1ConcRefine_mon);
if (_enabled) {
_enabled = false;
return _traversals;
} else {
return 0;
}
}
void ConcurrentG1Refine::wait_for_ConcurrentG1Refine_enabled() {
G1ConcRefine_mon->lock();
while (!_enabled) {
G1ConcRefine_mon->wait(Mutex::_no_safepoint_check_flag);
}
G1ConcRefine_mon->unlock();
_traversals = 0;
};
void ConcurrentG1Refine::set_pya_restart() {
// If we're using the log-based RS barrier, the above will cause
// in-progress traversals of completed log buffers to quit early; we will
// also abandon all other buffers.
if (G1RSBarrierUseQueue) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
dcqs.abandon_logs();
// Reset the post-yield actions.
_pya = PYA_continue;
_last_pya = PYA_continue;
} else {
_pya = PYA_restart;
}
}
void ConcurrentG1Refine::set_pya_cancel() {
_pya = PYA_cancel;
}
PostYieldAction ConcurrentG1Refine::get_pya() {
if (_pya != PYA_continue) {
jint val = _pya;
while (true) {
jint val_read = Atomic::cmpxchg(PYA_continue, &_pya, val);
if (val_read == val) {
PostYieldAction res = (PostYieldAction)val;
assert(res != PYA_continue, "Only the refine thread should reset.");
_last_pya = res;
return res;
} else {
val = val_read;
}
void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
if (_threads != NULL) {
for (int i = 0; i < _n_threads; i++) {
tc->do_thread(_threads[i]);
}
}
// QQQ WELL WHAT DO WE RETURN HERE???
// make up something!
return PYA_continue;
}
PostYieldAction ConcurrentG1Refine::get_last_pya() {
PostYieldAction res = _last_pya;
_last_pya = PYA_continue;
return res;
}
bool ConcurrentG1Refine::do_traversal() {
return _cg1rThread->do_traversal();
}
int ConcurrentG1Refine::add_card_count(jbyte* card_ptr) {
size_t card_num = (card_ptr - _ct_bot);

View File

@ -26,26 +26,9 @@
class ConcurrentG1RefineThread;
class G1RemSet;
// What to do after a yield:
enum PostYieldAction {
PYA_continue, // Continue the traversal
PYA_restart, // Restart
PYA_cancel // It's been completed by somebody else: cancel.
};
class ConcurrentG1Refine: public CHeapObj {
ConcurrentG1RefineThread* _cg1rThread;
volatile jint _pya;
PostYieldAction _last_pya;
static bool _enabled; // Protected by G1ConcRefine_mon.
unsigned _traversals;
// Number of cards processed during last refinement traversal.
unsigned _first_traversal;
unsigned _last_cards_during;
ConcurrentG1RefineThread** _threads;
int _n_threads;
// The cache for card refinement.
bool _use_cache;
bool _def_use_cache;
@ -74,37 +57,10 @@ class ConcurrentG1Refine: public CHeapObj {
~ConcurrentG1Refine();
void init(); // Accomplish some initialization that has to wait.
void stop();
// Enabled Conc refinement, waking up thread if necessary.
void enable();
// Returns the number of traversals performed since this refiner was enabled.
unsigned disable();
// Requires G1ConcRefine_mon to be held.
bool enabled() { return _enabled; }
// Returns only when G1 concurrent refinement has been enabled.
void wait_for_ConcurrentG1Refine_enabled();
// Do one concurrent refinement pass over the card table. Returns "true"
// if heuristics determine that another pass should be done immediately.
bool refine();
// Indicate that an in-progress refinement pass should start over.
void set_pya_restart();
// Indicate that an in-progress refinement pass should quit.
void set_pya_cancel();
// Get the appropriate post-yield action. Also sets last_pya.
PostYieldAction get_pya();
// The last PYA read by "get_pya".
PostYieldAction get_last_pya();
bool do_traversal();
ConcurrentG1RefineThread* cg1rThread() { return _cg1rThread; }
// Iterate over the conc refine threads
void threads_do(ThreadClosure *tc);
// If this is the first entry for the slot, writes into the cache and
// returns NULL. If it causes an eviction, returns the evicted pointer.
@ -129,4 +85,6 @@ class ConcurrentG1Refine: public CHeapObj {
void clear_and_record_card_counts();
void print_final_card_counts();
static size_t thread_num();
};

View File

@ -30,12 +30,14 @@
// The CM thread is created when the G1 garbage collector is used
ConcurrentG1RefineThread::
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r) :
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
int worker_id_offset, int worker_id) :
ConcurrentGCThread(),
_worker_id_offset(worker_id_offset),
_worker_id(worker_id),
_active(false),
_next(next),
_cg1r(cg1r),
_started(false),
_in_progress(false),
_do_traversal(false),
_vtime_accum(0.0),
_co_tracker(G1CRGroup),
_interval_ms(5.0)
@ -43,110 +45,6 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r) :
create_and_start();
}
const long timeout = 200; // ms.
void ConcurrentG1RefineThread::traversalBasedRefinement() {
_cg1r->wait_for_ConcurrentG1Refine_enabled();
MutexLocker x(G1ConcRefine_mon);
while (_cg1r->enabled()) {
MutexUnlocker ux(G1ConcRefine_mon);
ResourceMark rm;
HandleMark hm;
if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine starting pass");
_sts.join();
bool no_sleep = _cg1r->refine();
_sts.leave();
if (!no_sleep) {
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
// We do this only for the timeout; we don't expect this to be signalled.
CGC_lock->wait(Mutex::_no_safepoint_check_flag, timeout);
}
}
}
void ConcurrentG1RefineThread::queueBasedRefinement() {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
// Wait for completed log buffers to exist.
{
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
while (!_do_traversal && !dcqs.process_completed_buffers() &&
!_should_terminate) {
DirtyCardQ_CBL_mon->wait(Mutex::_no_safepoint_check_flag);
}
}
if (_should_terminate) {
return;
}
// Now we take them off (this doesn't hold locks while it applies
// closures.) (If we did a full collection, then we'll do a full
// traversal.
_sts.join();
if (_do_traversal) {
(void)_cg1r->refine();
switch (_cg1r->get_last_pya()) {
case PYA_cancel: case PYA_continue:
// Continue was caught and handled inside "refine". If it's still
// "continue" when we get here, we're done.
_do_traversal = false;
break;
case PYA_restart:
assert(_do_traversal, "Because of Full GC.");
break;
}
} else {
int n_logs = 0;
int lower_limit = 0;
double start_vtime_sec; // only used when G1SmoothConcRefine is on
int prev_buffer_num; // only used when G1SmoothConcRefine is on
if (G1SmoothConcRefine) {
lower_limit = 0;
start_vtime_sec = os::elapsedVTime();
prev_buffer_num = (int) dcqs.completed_buffers_num();
} else {
lower_limit = DCQBarrierProcessCompletedThreshold / 4; // For now.
}
while (dcqs.apply_closure_to_completed_buffer(0, lower_limit)) {
double end_vtime_sec;
double elapsed_vtime_sec;
int elapsed_vtime_ms;
int curr_buffer_num;
if (G1SmoothConcRefine) {
end_vtime_sec = os::elapsedVTime();
elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
elapsed_vtime_ms = (int) (elapsed_vtime_sec * 1000.0);
curr_buffer_num = (int) dcqs.completed_buffers_num();
if (curr_buffer_num > prev_buffer_num ||
curr_buffer_num > DCQBarrierProcessCompletedThreshold) {
decreaseInterval(elapsed_vtime_ms);
} else if (curr_buffer_num < prev_buffer_num) {
increaseInterval(elapsed_vtime_ms);
}
}
sample_young_list_rs_lengths();
_co_tracker.update(false);
if (G1SmoothConcRefine) {
prev_buffer_num = curr_buffer_num;
_sts.leave();
os::sleep(Thread::current(), (jlong) _interval_ms, false);
_sts.join();
start_vtime_sec = os::elapsedVTime();
}
n_logs++;
}
// Make sure we harvest the PYA, if any.
(void)_cg1r->get_pya();
}
_sts.leave();
}
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1p = g1h->g1_policy();
@ -182,15 +80,97 @@ void ConcurrentG1RefineThread::run() {
_co_tracker.start();
while (!_should_terminate) {
// wait until started is set.
if (G1RSBarrierUseQueue) {
queueBasedRefinement();
} else {
traversalBasedRefinement();
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
// Wait for completed log buffers to exist.
{
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
while (((_worker_id == 0 && !dcqs.process_completed_buffers()) ||
(_worker_id > 0 && !is_active())) &&
!_should_terminate) {
DirtyCardQ_CBL_mon->wait(Mutex::_no_safepoint_check_flag);
}
}
if (_should_terminate) {
return;
}
// Now we take them off (this doesn't hold locks while it applies
// closures.) (If we did a full collection, then we'll do a full
// traversal.
_sts.join();
_co_tracker.update();
int n_logs = 0;
int lower_limit = 0;
double start_vtime_sec; // only used when G1SmoothConcRefine is on
int prev_buffer_num; // only used when G1SmoothConcRefine is on
// This thread activation threshold
int threshold = DCQBarrierProcessCompletedThreshold * _worker_id;
// Next thread activation threshold
int next_threshold = threshold + DCQBarrierProcessCompletedThreshold;
int deactivation_threshold = MAX2<int>(threshold - DCQBarrierProcessCompletedThreshold / 2, 0);
if (G1SmoothConcRefine) {
lower_limit = 0;
start_vtime_sec = os::elapsedVTime();
prev_buffer_num = (int) dcqs.completed_buffers_num();
} else {
lower_limit = DCQBarrierProcessCompletedThreshold / 4; // For now.
}
while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, lower_limit)) {
double end_vtime_sec;
double elapsed_vtime_sec;
int elapsed_vtime_ms;
int curr_buffer_num = (int) dcqs.completed_buffers_num();
if (G1SmoothConcRefine) {
end_vtime_sec = os::elapsedVTime();
elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
elapsed_vtime_ms = (int) (elapsed_vtime_sec * 1000.0);
if (curr_buffer_num > prev_buffer_num ||
curr_buffer_num > next_threshold) {
decreaseInterval(elapsed_vtime_ms);
} else if (curr_buffer_num < prev_buffer_num) {
increaseInterval(elapsed_vtime_ms);
}
}
if (_worker_id == 0) {
sample_young_list_rs_lengths();
} else if (curr_buffer_num < deactivation_threshold) {
// If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again.
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
deactivate();
if (G1TraceConcurrentRefinement) {
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d", _worker_id);
}
break;
}
_co_tracker.update(false);
// Check if we need to activate the next thread.
if (curr_buffer_num > next_threshold && _next != NULL && !_next->is_active()) {
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
_next->activate();
DirtyCardQ_CBL_mon->notify_all();
if (G1TraceConcurrentRefinement) {
gclog_or_tty->print_cr("G1-Refine-activated worker %d", _next->_worker_id);
}
}
if (G1SmoothConcRefine) {
prev_buffer_num = curr_buffer_num;
_sts.leave();
os::sleep(Thread::current(), (jlong) _interval_ms, false);
_sts.join();
start_vtime_sec = os::elapsedVTime();
}
n_logs++;
}
_co_tracker.update(false);
_sts.leave();
if (os::supports_vtime()) {
_vtime_accum = (os::elapsedVTime() - _vtime_start);
} else {
@ -207,9 +187,9 @@ void ConcurrentG1RefineThread::run() {
void ConcurrentG1RefineThread::yield() {
if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine-yield");
if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield");
_sts.yield("G1 refine");
if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine-yield-end");
if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield-end");
}
void ConcurrentG1RefineThread::stop() {
@ -230,7 +210,7 @@ void ConcurrentG1RefineThread::stop() {
Terminator_lock->wait();
}
}
if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine-stop");
if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-stop");
}
void ConcurrentG1RefineThread::print() {
@ -238,7 +218,3 @@ void ConcurrentG1RefineThread::print() {
Thread::print();
gclog_or_tty->cr();
}
void ConcurrentG1RefineThread::set_do_traversal(bool b) {
_do_traversal = b;
}

View File

@ -33,21 +33,27 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
double _vtime_start; // Initial virtual time.
double _vtime_accum; // Initial virtual time.
int _worker_id;
int _worker_id_offset;
// The refinement threads collection is linked list. A predecessor can activate a successor
// when the number of the rset update buffer crosses a certain threshold. A successor
// would self-deactivate when the number of the buffers falls below the threshold.
bool _active;
ConcurrentG1RefineThread * _next;
public:
virtual void run();
bool is_active() { return _active; }
void activate() { _active = true; }
void deactivate() { _active = false; }
private:
ConcurrentG1Refine* _cg1r;
bool _started;
bool _in_progress;
volatile bool _restart;
COTracker _co_tracker;
double _interval_ms;
bool _do_traversal;
void decreaseInterval(int processing_time_ms) {
double min_interval_ms = (double) processing_time_ms;
_interval_ms = 0.8 * _interval_ms;
@ -63,16 +69,13 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
void sleepBeforeNextCycle();
void traversalBasedRefinement();
void queueBasedRefinement();
// For use by G1CollectedHeap, which is a friend.
static SuspendibleThreadSet* sts() { return &_sts; }
public:
// Constructor
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r);
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
int worker_id_offset, int worker_id);
// Printing
void print();
@ -82,23 +85,11 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
ConcurrentG1Refine* cg1r() { return _cg1r; }
void set_started() { _started = true; }
void clear_started() { _started = false; }
bool started() { return _started; }
void set_in_progress() { _in_progress = true; }
void clear_in_progress() { _in_progress = false; }
bool in_progress() { return _in_progress; }
void set_do_traversal(bool b);
bool do_traversal() { return _do_traversal; }
void sample_young_list_rs_lengths();
// Yield for GC
void yield();
// shutdown
static void stop();
void stop();
};

View File

@ -448,8 +448,8 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", "
"heap end = "PTR_FORMAT, _heap_start, _heap_end);
_markStack.allocate(G1CMStackSize);
_regionStack.allocate(G1CMRegionStackSize);
_markStack.allocate(G1MarkStackSize);
_regionStack.allocate(G1MarkRegionStackSize);
// Create & start a ConcurrentMark thread.
if (G1ConcMark) {
@ -499,20 +499,21 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
_marking_task_overhead = 1.0;
} else {
if (ParallelMarkingThreads > 0) {
// notice that ParallelMarkingThreads overwrites G1MarkingOverheadPerc
// notice that ParallelMarkingThreads overwrites G1MarkingOverheadPercent
// if both are set
_parallel_marking_threads = ParallelMarkingThreads;
_sleep_factor = 0.0;
_marking_task_overhead = 1.0;
} else if (G1MarkingOverheadPerc > 0) {
} else if (G1MarkingOverheadPercent > 0) {
// we will calculate the number of parallel marking threads
// based on a target overhead with respect to the soft real-time
// goal
double marking_overhead = (double) G1MarkingOverheadPerc / 100.0;
double marking_overhead = (double) G1MarkingOverheadPercent / 100.0;
double overall_cm_overhead =
(double) G1MaxPauseTimeMS * marking_overhead / (double) G1TimeSliceMS;
(double) MaxGCPauseMillis * marking_overhead /
(double) GCPauseIntervalMillis;
double cpu_ratio = 1.0 / (double) os::processor_count();
double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio);
double marking_task_overhead =
@ -1747,7 +1748,7 @@ void ConcurrentMark::cleanup() {
g1h->increment_total_collections();
#ifndef PRODUCT
if (G1VerifyConcMark) {
if (VerifyDuringGC) {
G1CollectedHeap::heap()->prepare_for_verify();
G1CollectedHeap::heap()->verify(true,false);
}

View File

@ -136,9 +136,6 @@ void ConcurrentMarkThread::run() {
iter++;
if (!cm()->has_aborted()) {
_cm->markFromRoots();
} else {
if (TraceConcurrentMark)
gclog_or_tty->print_cr("CM-skip-mark-from-roots");
}
double mark_end_time = os::elapsedVTime();
@ -163,9 +160,6 @@ void ConcurrentMarkThread::run() {
sprintf(verbose_str, "GC remark");
VM_CGC_Operation op(&final_cl, verbose_str);
VMThread::execute(&op);
} else {
if (TraceConcurrentMark)
gclog_or_tty->print_cr("CM-skip-remark");
}
if (cm()->restart_for_overflow() &&
G1TraceMarkStackOverflow) {
@ -208,8 +202,6 @@ void ConcurrentMarkThread::run() {
count_end_sec - count_start_sec);
}
}
} else {
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-skip-end-game");
}
double end_time = os::elapsedVTime();
_vtime_count_accum += (end_time - counting_start_time);
@ -230,7 +222,6 @@ void ConcurrentMarkThread::run() {
VM_CGC_Operation op(&cl_cl, verbose_str);
VMThread::execute(&op);
} else {
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-skip-cleanup");
G1CollectedHeap::heap()->set_marking_complete();
}
@ -287,9 +278,7 @@ void ConcurrentMarkThread::run() {
void ConcurrentMarkThread::yield() {
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-yield");
_sts.yield("Concurrent Mark");
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-yield-end");
}
void ConcurrentMarkThread::stop() {
@ -299,7 +288,6 @@ void ConcurrentMarkThread::stop() {
while (!_has_terminated) {
Terminator_lock->wait();
}
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-stop");
}
void ConcurrentMarkThread::print() {
@ -314,12 +302,10 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() {
// below while the world is otherwise stopped.
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
while (!started()) {
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-sleeping");
CGC_lock->wait(Mutex::_no_safepoint_check_flag);
}
set_in_progress();
clear_started();
if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-starting");
}
// Note: this method, although exported by the ConcurrentMarkSweepThread,

View File

@ -80,5 +80,5 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
void yield();
// shutdown
static void stop();
void stop();
};

View File

@ -73,7 +73,7 @@ class ConcurrentZFThread: public ConcurrentGCThread {
// while holding the ZF_needed_mon lock.
// shutdown
static void stop();
void stop();
// Stats
static void note_region_alloc() {_region_allocs++; }

View File

@ -71,11 +71,11 @@ DirtyCardQueueSet::DirtyCardQueueSet() :
_all_active = true;
}
// Determines how many mutator threads can process the buffers in parallel.
size_t DirtyCardQueueSet::num_par_ids() {
return MAX2(ParallelGCThreads, (size_t)2);
return os::processor_count();
}
void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
int max_completed_queue,
Mutex* lock, PtrQueueSet* fl_owner) {
@ -85,8 +85,6 @@ void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
_shared_dirty_card_queue.set_lock(lock);
_free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
bool b = _free_ids->claim_perm_id(0);
guarantee(b, "Must reserve id zero for concurrent refinement thread.");
}
void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
@ -234,7 +232,7 @@ bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
nd = get_completed_buffer_lock(stop_at);
}
bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
if (res) _processed_buffers_rs_thread++;
if (res) Atomic::inc(&_processed_buffers_rs_thread);
return res;
}

View File

@ -446,8 +446,61 @@ void YoungList::print() {
gclog_or_tty->print_cr("");
}
void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr)
{
// Claim the right to put the region on the dirty cards region list
// by installing a self pointer.
HeapRegion* next = hr->get_next_dirty_cards_region();
if (next == NULL) {
HeapRegion* res = (HeapRegion*)
Atomic::cmpxchg_ptr(hr, hr->next_dirty_cards_region_addr(),
NULL);
if (res == NULL) {
HeapRegion* head;
do {
// Put the region to the dirty cards region list.
head = _dirty_cards_region_list;
next = (HeapRegion*)
Atomic::cmpxchg_ptr(hr, &_dirty_cards_region_list, head);
if (next == head) {
assert(hr->get_next_dirty_cards_region() == hr,
"hr->get_next_dirty_cards_region() != hr");
if (next == NULL) {
// The last region in the list points to itself.
hr->set_next_dirty_cards_region(hr);
} else {
hr->set_next_dirty_cards_region(next);
}
}
} while (next != head);
}
}
}
HeapRegion* G1CollectedHeap::pop_dirty_cards_region()
{
HeapRegion* head;
HeapRegion* hr;
do {
head = _dirty_cards_region_list;
if (head == NULL) {
return NULL;
}
HeapRegion* new_head = head->get_next_dirty_cards_region();
if (head == new_head) {
// The last region.
new_head = NULL;
}
hr = (HeapRegion*)Atomic::cmpxchg_ptr(new_head, &_dirty_cards_region_list,
head);
} while (hr != head);
assert(hr != NULL, "invariant");
hr->set_next_dirty_cards_region(NULL);
return hr;
}
void G1CollectedHeap::stop_conc_gc_threads() {
_cg1r->cg1rThread()->stop();
_cg1r->stop();
_czft->stop();
_cmThread->stop();
}
@ -528,7 +581,7 @@ HeapRegion* G1CollectedHeap::newAllocRegion_work(size_t word_size,
res->zero_fill_state() == HeapRegion::Allocated)),
"Non-young alloc Regions must be zero filled (and non-H)");
if (G1TraceRegions) {
if (G1PrintRegions) {
if (res != NULL) {
gclog_or_tty->print_cr("new alloc region %d:["PTR_FORMAT", "PTR_FORMAT"], "
"top "PTR_FORMAT,
@ -1001,12 +1054,8 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
gc_epilogue(true);
// Abandon concurrent refinement. This must happen last: in the
// dirty-card logging system, some cards may be dirty by weak-ref
// processing, and may be enqueued. But the whole card table is
// dirtied, so this should abandon those logs, and set "do_traversal"
// to true.
concurrent_g1_refine()->set_pya_restart();
// Discard all rset updates
JavaThread::dirty_card_queue_set().abandon_logs();
assert(!G1DeferredRSUpdate
|| (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any");
assert(regions_accounted_for(), "Region leakage!");
@ -1333,7 +1382,8 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_gc_time_stamp(0),
_surviving_young_words(NULL),
_in_cset_fast_test(NULL),
_in_cset_fast_test_base(NULL) {
_in_cset_fast_test_base(NULL),
_dirty_cards_region_list(NULL) {
_g1h = this; // To catch bugs.
if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
vm_exit_during_initialization("Failed necessary allocation.");
@ -1521,12 +1571,12 @@ jint G1CollectedHeap::initialize() {
SATB_Q_FL_lock,
0,
Shared_SATB_Q_lock);
if (G1RSBarrierUseQueue) {
JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
DirtyCardQ_FL_lock,
G1DirtyCardQueueMax,
Shared_DirtyCardQ_lock);
}
JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
DirtyCardQ_FL_lock,
G1DirtyCardQueueMax,
Shared_DirtyCardQ_lock);
if (G1DeferredRSUpdate) {
dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
DirtyCardQ_FL_lock,
@ -2249,6 +2299,15 @@ void G1CollectedHeap::print_on(outputStream* st) const {
_hrs->iterate(&blk);
}
class PrintOnThreadsClosure : public ThreadClosure {
outputStream* _st;
public:
PrintOnThreadsClosure(outputStream* st) : _st(st) { }
virtual void do_thread(Thread *t) {
t->print_on(_st);
}
};
void G1CollectedHeap::print_gc_threads_on(outputStream* st) const {
if (ParallelGCThreads > 0) {
workers()->print_worker_threads();
@ -2256,8 +2315,9 @@ void G1CollectedHeap::print_gc_threads_on(outputStream* st) const {
st->print("\"G1 concurrent mark GC Thread\" ");
_cmThread->print();
st->cr();
st->print("\"G1 concurrent refinement GC Thread\" ");
_cg1r->cg1rThread()->print_on(st);
st->print("\"G1 concurrent refinement GC Threads\" ");
PrintOnThreadsClosure p(st);
_cg1r->threads_do(&p);
st->cr();
st->print("\"G1 zero-fill GC Thread\" ");
_czft->print_on(st);
@ -2269,7 +2329,7 @@ void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const {
workers()->threads_do(tc);
}
tc->do_thread(_cmThread);
tc->do_thread(_cg1r->cg1rThread());
_cg1r->threads_do(tc);
tc->do_thread(_czft);
}
@ -2282,13 +2342,13 @@ void G1CollectedHeap::print_tracing_info() const {
// to that.
g1_policy()->print_tracing_info();
}
if (SummarizeG1RSStats) {
if (G1SummarizeRSetStats) {
g1_rem_set()->print_summary_info();
}
if (SummarizeG1ConcMark) {
if (G1SummarizeConcurrentMark) {
concurrent_mark()->print_summary_info();
}
if (SummarizeG1ZFStats) {
if (G1SummarizeZFStats) {
ConcurrentZFThread::print_summary_info();
}
g1_policy()->print_yg_surv_rate_info();
@ -3255,7 +3315,7 @@ void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) {
HeapRegion* r = heap_region_containing(old);
if (!r->evacuation_failed()) {
r->set_evacuation_failed(true);
if (G1TraceRegions) {
if (G1PrintRegions) {
gclog_or_tty->print("evacuation failed in heap region "PTR_FORMAT" "
"["PTR_FORMAT","PTR_FORMAT")\n",
r, r->bottom(), r->end());
@ -3466,7 +3526,7 @@ private:
}
static size_t gclab_word_size() {
return ParallelGCG1AllocBufferSize / HeapWordSize;
return G1ParallelGCAllocBufferSize / HeapWordSize;
}
static size_t bitmap_size_in_bits() {
@ -3616,7 +3676,7 @@ private:
public:
G1ParGCAllocBuffer() :
ParGCAllocBuffer(ParallelGCG1AllocBufferSize / HeapWordSize),
ParGCAllocBuffer(G1ParallelGCAllocBufferSize / HeapWordSize),
_during_marking(G1CollectedHeap::heap()->mark_in_progress()),
_bitmap(G1CollectedHeap::heap()->reserved_region().start()),
_retired(false)
@ -3812,14 +3872,14 @@ public:
HeapWord* obj = NULL;
if (word_sz * 100 <
(size_t)(ParallelGCG1AllocBufferSize / HeapWordSize) *
(size_t)(G1ParallelGCAllocBufferSize / HeapWordSize) *
ParallelGCBufferWastePct) {
G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
add_to_alloc_buffer_waste(alloc_buf->words_remaining());
alloc_buf->retire(false, false);
HeapWord* buf =
_g1h->par_allocate_during_gc(purpose, ParallelGCG1AllocBufferSize / HeapWordSize);
_g1h->par_allocate_during_gc(purpose, G1ParallelGCAllocBufferSize / HeapWordSize);
if (buf == NULL) return NULL; // Let caller handle allocation failure.
// Otherwise.
alloc_buf->set_buf(buf);
@ -4331,7 +4391,7 @@ public:
_g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
_g1h->g1_policy()->record_termination_time(i, term_ms);
}
if (G1UseSurvivorSpace) {
if (G1UseSurvivorSpaces) {
_g1h->g1_policy()->record_thread_age_table(pss.age_table());
}
_g1h->update_surviving_young_words(pss.surviving_young_words()+1);
@ -4435,28 +4495,6 @@ g1_process_strong_roots(bool collecting_perm_gen,
// XXX What should this be doing in the parallel case?
g1_policy()->record_collection_pause_end_CH_strong_roots();
if (G1VerifyRemSet) {
// :::: FIXME ::::
// The stupid remembered set doesn't know how to filter out dead
// objects, which the smart one does, and so when it is created
// and then compared the number of entries in each differs and
// the verification code fails.
guarantee(false, "verification code is broken, see note");
// Let's make sure that the current rem set agrees with the stupidest
// one possible!
bool refs_enabled = ref_processor()->discovery_enabled();
if (refs_enabled) ref_processor()->disable_discovery();
StupidG1RemSet stupid(this);
count_closure.n = 0;
stupid.oops_into_collection_set_do(&count_closure, worker_i);
int stupid_n = count_closure.n;
count_closure.n = 0;
g1_rem_set()->oops_into_collection_set_do(&count_closure, worker_i);
guarantee(count_closure.n == stupid_n, "Old and new rem sets differ.");
gclog_or_tty->print_cr("\nFound %d pointers in heap RS.", count_closure.n);
if (refs_enabled) ref_processor()->enable_discovery();
}
if (scan_so != NULL) {
scan_scan_only_set(scan_so, worker_i);
}
@ -4707,15 +4745,58 @@ void G1CollectedHeap::dirtyCardsForYoungRegions(CardTableModRefBS* ct_bs, HeapRe
}
}
class G1ParCleanupCTTask : public AbstractGangTask {
CardTableModRefBS* _ct_bs;
G1CollectedHeap* _g1h;
public:
G1ParCleanupCTTask(CardTableModRefBS* ct_bs,
G1CollectedHeap* g1h) :
AbstractGangTask("G1 Par Cleanup CT Task"),
_ct_bs(ct_bs),
_g1h(g1h)
{ }
void work(int i) {
HeapRegion* r;
while (r = _g1h->pop_dirty_cards_region()) {
clear_cards(r);
}
}
void clear_cards(HeapRegion* r) {
// Cards for Survivor and Scan-Only regions will be dirtied later.
if (!r->is_scan_only() && !r->is_survivor()) {
_ct_bs->clear(MemRegion(r->bottom(), r->end()));
}
}
};
void G1CollectedHeap::cleanUpCardTable() {
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
double start = os::elapsedTime();
ct_bs->clear(_g1_committed);
// Iterate over the dirty cards region list.
G1ParCleanupCTTask cleanup_task(ct_bs, this);
if (ParallelGCThreads > 0) {
set_par_threads(workers()->total_workers());
workers()->run_task(&cleanup_task);
set_par_threads(0);
} else {
while (_dirty_cards_region_list) {
HeapRegion* r = _dirty_cards_region_list;
cleanup_task.clear_cards(r);
_dirty_cards_region_list = r->get_next_dirty_cards_region();
if (_dirty_cards_region_list == r) {
// The last region.
_dirty_cards_region_list = NULL;
}
r->set_next_dirty_cards_region(NULL);
}
}
// now, redirty the cards of the scan-only and survivor regions
// (it seemed faster to do it this way, instead of iterating over
// all regions and then clearing / dirtying as approprite)
// all regions and then clearing / dirtying as appropriate)
dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region());
dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region());

View File

@ -158,6 +158,7 @@ class G1CollectedHeap : public SharedHeap {
friend class RegionSorter;
friend class CountRCClosure;
friend class EvacPopObjClosure;
friend class G1ParCleanupCTTask;
// Other related classes.
friend class G1MarkSweep;
@ -1191,6 +1192,16 @@ public:
ConcurrentMark* concurrent_mark() const { return _cm; }
ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
// The dirty cards region list is used to record a subset of regions
// whose cards need clearing. The list if populated during the
// remembered set scanning and drained during the card table
// cleanup. Although the methods are reentrant, population/draining
// phases must not overlap. For synchronization purposes the last
// element on the list points to itself.
HeapRegion* _dirty_cards_region_list;
void push_dirty_cards_region(HeapRegion* hr);
HeapRegion* pop_dirty_cards_region();
public:
void stop_conc_gc_threads();

View File

@ -37,8 +37,9 @@ G1CollectedHeap::heap_region_containing(const void* addr) const {
inline HeapRegion*
G1CollectedHeap::heap_region_containing_raw(const void* addr) const {
assert(_g1_reserved.contains(addr), "invariant");
size_t index = ((intptr_t) addr - (intptr_t) _g1_reserved.start())
>> HeapRegion::LogOfHRGrainBytes;
size_t index = pointer_delta(addr, _g1_reserved.start(), 1)
>> HeapRegion::LogOfHRGrainBytes;
HeapRegion* res = _hrs->at(index);
assert(res == _hrs->addr_to_region(addr), "sanity");
return res;

View File

@ -136,7 +136,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
_scanned_cards_seq(new TruncatedSeq(TruncatedSeqLength)),
_rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)),
_pause_time_target_ms((double) G1MaxPauseTimeMS),
_pause_time_target_ms((double) MaxGCPauseMillis),
// </NEW PREDICTION>
@ -167,11 +167,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
_all_full_gc_times_ms(new NumberSeq()),
_conc_refine_enabled(0),
_conc_refine_zero_traversals(0),
_conc_refine_max_traversals(0),
_conc_refine_current_delta(G1ConcRefineInitialDelta),
// G1PausesBtwnConcMark defaults to -1
// so the hack is to do the cast QQQ FIXME
_pauses_btwn_concurrent_mark((size_t)G1PausesBtwnConcMark),
@ -220,7 +215,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
_par_last_termination_times_ms = new double[_parallel_gc_threads];
// start conservatively
_expensive_region_limit_ms = 0.5 * (double) G1MaxPauseTimeMS;
_expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis;
// <NEW PREDICTION>
@ -249,12 +244,12 @@ G1CollectorPolicy::G1CollectorPolicy() :
// </NEW PREDICTION>
double time_slice = (double) G1TimeSliceMS / 1000.0;
double max_gc_time = (double) G1MaxPauseTimeMS / 1000.0;
double time_slice = (double) GCPauseIntervalMillis / 1000.0;
double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
guarantee(max_gc_time < time_slice,
"Max GC time should not be greater than the time slice");
_mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
_sigma = (double) G1ConfidencePerc / 100.0;
_sigma = (double) G1ConfidencePercent / 100.0;
// start conservatively (around 50ms is about right)
_concurrent_mark_init_times_ms->add(0.05);
@ -262,7 +257,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
_concurrent_mark_cleanup_times_ms->add(0.20);
_tenuring_threshold = MaxTenuringThreshold;
if (G1UseSurvivorSpace) {
if (G1UseSurvivorSpaces) {
// if G1FixedSurvivorSpaceSize is 0 which means the size is not
// fixed, then _max_survivor_regions will be calculated at
// calculate_young_list_target_config during initialization
@ -451,7 +446,7 @@ void G1CollectorPolicy::calculate_young_list_target_config(size_t rs_lengths) {
guarantee( adaptive_young_list_length(), "pre-condition" );
double start_time_sec = os::elapsedTime();
size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePerc);
size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePercent);
min_reserve_perc = MIN2((size_t) 50, min_reserve_perc);
size_t reserve_regions =
(size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0);
@ -1109,7 +1104,7 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
_short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length);
tag_scan_only(short_lived_so_length);
if (G1UseSurvivorSpace) {
if (G1UseSurvivorSpaces) {
_survivors_age_table.clear();
}
@ -1634,9 +1629,8 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
print_par_stats(2, "Update RS (Start)", _par_last_update_rs_start_times_ms, false);
print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
if (G1RSBarrierUseQueue)
print_par_buffers(3, "Processed Buffers",
_par_last_update_rs_processed_buffers, true);
print_par_buffers(3, "Processed Buffers",
_par_last_update_rs_processed_buffers, true);
print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms);
print_par_stats(2, "Scan-Only Scanning", _par_last_scan_only_times_ms);
@ -1649,9 +1643,8 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
} else {
print_stats(1, "Update RS", update_rs_time);
if (G1RSBarrierUseQueue)
print_stats(2, "Processed Buffers",
(int)update_rs_processed_buffers);
print_stats(2, "Processed Buffers",
(int)update_rs_processed_buffers);
print_stats(1, "Ext Root Scanning", ext_root_scan_time);
print_stats(1, "Mark Stack Scanning", mark_stack_scan_time);
print_stats(1, "Scan-Only Scanning", scan_only_time);
@ -1826,11 +1819,11 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
_rs_lengths_seq->add((double) _max_rs_lengths);
double expensive_region_limit_ms =
(double) G1MaxPauseTimeMS - predict_constant_other_time_ms();
(double) MaxGCPauseMillis - predict_constant_other_time_ms();
if (expensive_region_limit_ms < 0.0) {
// this means that the other time was predicted to be longer than
// than the max pause time
expensive_region_limit_ms = (double) G1MaxPauseTimeMS;
expensive_region_limit_ms = (double) MaxGCPauseMillis;
}
_expensive_region_limit_ms = expensive_region_limit_ms;
@ -2093,24 +2086,24 @@ void G1CollectorPolicy::update_recent_gc_times(double end_time_sec,
}
double G1CollectorPolicy::recent_avg_time_for_pauses_ms() {
if (_recent_pause_times_ms->num() == 0) return (double) G1MaxPauseTimeMS;
if (_recent_pause_times_ms->num() == 0) return (double) MaxGCPauseMillis;
else return _recent_pause_times_ms->avg();
}
double G1CollectorPolicy::recent_avg_time_for_CH_strong_ms() {
if (_recent_CH_strong_roots_times_ms->num() == 0)
return (double)G1MaxPauseTimeMS/3.0;
return (double)MaxGCPauseMillis/3.0;
else return _recent_CH_strong_roots_times_ms->avg();
}
double G1CollectorPolicy::recent_avg_time_for_G1_strong_ms() {
if (_recent_G1_strong_roots_times_ms->num() == 0)
return (double)G1MaxPauseTimeMS/3.0;
return (double)MaxGCPauseMillis/3.0;
else return _recent_G1_strong_roots_times_ms->avg();
}
double G1CollectorPolicy::recent_avg_time_for_evac_ms() {
if (_recent_evac_times_ms->num() == 0) return (double)G1MaxPauseTimeMS/3.0;
if (_recent_evac_times_ms->num() == 0) return (double)MaxGCPauseMillis/3.0;
else return _recent_evac_times_ms->avg();
}
@ -2197,17 +2190,18 @@ G1CollectorPolicy::conservative_avg_survival_fraction_work(double avg,
}
size_t G1CollectorPolicy::expansion_amount() {
if ((int)(recent_avg_pause_time_ratio() * 100.0) > G1GCPct) {
// We will double the existing space, or take G1ExpandByPctOfAvail % of
// the available expansion space, whichever is smaller, bounded below
// by a minimum expansion (unless that's all that's left.)
if ((int)(recent_avg_pause_time_ratio() * 100.0) > G1GCPercent) {
// We will double the existing space, or take
// G1ExpandByPercentOfAvailable % of the available expansion
// space, whichever is smaller, bounded below by a minimum
// expansion (unless that's all that's left.)
const size_t min_expand_bytes = 1*M;
size_t reserved_bytes = _g1->g1_reserved_obj_bytes();
size_t committed_bytes = _g1->capacity();
size_t uncommitted_bytes = reserved_bytes - committed_bytes;
size_t expand_bytes;
size_t expand_bytes_via_pct =
uncommitted_bytes * G1ExpandByPctOfAvail / 100;
uncommitted_bytes * G1ExpandByPercentOfAvailable / 100;
expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes);
expand_bytes = MAX2(expand_bytes, min_expand_bytes);
expand_bytes = MIN2(expand_bytes, uncommitted_bytes);
@ -2466,18 +2460,6 @@ void G1CollectorPolicy::print_tracing_info() const {
(double) _region_num_young / (double) all_region_num * 100.0,
_region_num_tenured,
(double) _region_num_tenured / (double) all_region_num * 100.0);
if (!G1RSBarrierUseQueue) {
gclog_or_tty->print_cr("Of %d times conc refinement was enabled, %d (%7.2f%%) "
"did zero traversals.",
_conc_refine_enabled, _conc_refine_zero_traversals,
_conc_refine_enabled > 0 ?
100.0 * (float)_conc_refine_zero_traversals/
(float)_conc_refine_enabled : 0.0);
gclog_or_tty->print_cr(" Max # of traversals = %d.",
_conc_refine_max_traversals);
gclog_or_tty->print_cr("");
}
}
if (TraceGen1Time) {
if (_all_full_gc_times_ms->num() > 0) {
@ -2499,38 +2481,6 @@ void G1CollectorPolicy::print_yg_surv_rate_info() const {
#endif // PRODUCT
}
void G1CollectorPolicy::update_conc_refine_data() {
unsigned traversals = _g1->concurrent_g1_refine()->disable();
if (traversals == 0) _conc_refine_zero_traversals++;
_conc_refine_max_traversals = MAX2(_conc_refine_max_traversals,
(size_t)traversals);
if (G1PolicyVerbose > 1)
gclog_or_tty->print_cr("Did a CR traversal series: %d traversals.", traversals);
double multiplier = 1.0;
if (traversals == 0) {
multiplier = 4.0;
} else if (traversals > (size_t)G1ConcRefineTargTraversals) {
multiplier = 1.0/1.5;
} else if (traversals < (size_t)G1ConcRefineTargTraversals) {
multiplier = 1.5;
}
if (G1PolicyVerbose > 1) {
gclog_or_tty->print_cr(" Multiplier = %7.2f.", multiplier);
gclog_or_tty->print(" Delta went from %d regions to ",
_conc_refine_current_delta);
}
_conc_refine_current_delta =
MIN2(_g1->n_regions(),
(size_t)(_conc_refine_current_delta * multiplier));
_conc_refine_current_delta =
MAX2(_conc_refine_current_delta, (size_t)1);
if (G1PolicyVerbose > 1) {
gclog_or_tty->print_cr("%d regions.", _conc_refine_current_delta);
}
_conc_refine_enabled++;
}
bool
G1CollectorPolicy::should_add_next_region_to_young_list() {
assert(in_young_gc_mode(), "should be in young GC mode");
@ -2591,7 +2541,7 @@ size_t G1CollectorPolicy::max_regions(int purpose) {
// Calculates survivor space parameters.
void G1CollectorPolicy::calculate_survivors_policy()
{
if (!G1UseSurvivorSpace) {
if (!G1UseSurvivorSpaces) {
return;
}
if (G1FixedSurvivorSpaceSize == 0) {
@ -2851,7 +2801,7 @@ record_concurrent_mark_cleanup_end(size_t freed_bytes,
// estimate of the number of live bytes.
void G1CollectorPolicy::
add_to_collection_set(HeapRegion* hr) {
if (G1TraceRegions) {
if (G1PrintRegions) {
gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], "
"top "PTR_FORMAT", young %s",
hr->hrs_index(), hr->bottom(), hr->end(),

View File

@ -637,18 +637,6 @@ protected:
// The number of collection pauses at the end of the last mark.
size_t _n_pauses_at_mark_end;
// ==== This section is for stats related to starting Conc Refinement on time.
size_t _conc_refine_enabled;
size_t _conc_refine_zero_traversals;
size_t _conc_refine_max_traversals;
// In # of heap regions.
size_t _conc_refine_current_delta;
// At the beginning of a collection pause, update the variables above,
// especially the "delta".
void update_conc_refine_data();
// ====
// Stash a pointer to the g1 heap.
G1CollectedHeap* _g1;

View File

@ -57,7 +57,7 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
mark_sweep_phase1(marked_for_unloading, clear_all_softrefs);
if (G1VerifyConcMark) {
if (VerifyDuringGC) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
g1h->checkConcurrentMark();
}

View File

@ -105,28 +105,6 @@ StupidG1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
_g1->heap_region_iterate(&rc);
}
class UpdateRSOutOfRegionClosure: public HeapRegionClosure {
G1CollectedHeap* _g1h;
ModRefBarrierSet* _mr_bs;
UpdateRSOopClosure _cl;
int _worker_i;
public:
UpdateRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) :
_cl(g1->g1_rem_set()->as_HRInto_G1RemSet(), worker_i),
_mr_bs(g1->mr_bs()),
_worker_i(worker_i),
_g1h(g1)
{}
bool doHeapRegion(HeapRegion* r) {
if (!r->in_collection_set() && !r->continuesHumongous()) {
_cl.set_from(r);
r->set_next_filter_kind(HeapRegionDCTOC::OutOfRegionFilterKind);
_mr_bs->mod_oop_in_space_iterate(r, &_cl, true, true);
}
return false;
}
};
class VerifyRSCleanCardOopClosure: public OopClosure {
G1CollectedHeap* _g1;
public:
@ -180,6 +158,7 @@ class ScanRSClosure : public HeapRegionClosure {
CardTableModRefBS *_ct_bs;
int _worker_i;
bool _try_claimed;
size_t _min_skip_distance, _max_skip_distance;
public:
ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
_oc(oc),
@ -191,6 +170,8 @@ public:
_g1h = G1CollectedHeap::heap();
_bot_shared = _g1h->bot_shared();
_ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
_min_skip_distance = 16;
_max_skip_distance = 2 * _g1h->n_par_threads() * _min_skip_distance;
}
void set_try_claimed() { _try_claimed = true; }
@ -238,6 +219,7 @@ public:
HeapRegionRemSet* hrrs = r->rem_set();
if (hrrs->iter_is_complete()) return false; // All done.
if (!_try_claimed && !hrrs->claim_iter()) return false;
_g1h->push_dirty_cards_region(r);
// If we didn't return above, then
// _try_claimed || r->claim_iter()
// is true: either we're supposed to work on claimed-but-not-complete
@ -245,9 +227,13 @@ public:
HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i);
hrrs->init_iterator(iter);
size_t card_index;
size_t skip_distance = 0, current_card = 0, jump_to_card = 0;
while (iter->has_next(card_index)) {
if (current_card < jump_to_card) {
++current_card;
continue;
}
HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
#if 0
gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
card_start, card_start + CardTableModRefBS::card_size_in_words);
@ -257,20 +243,32 @@ public:
assert(card_region != NULL, "Yielding cards not in the heap?");
_cards++;
if (!card_region->in_collection_set()) {
// If the card is dirty, then we will scan it during updateRS.
if (!_ct_bs->is_card_claimed(card_index) &&
!_ct_bs->is_card_dirty(card_index)) {
assert(_ct_bs->is_card_clean(card_index) ||
_ct_bs->is_card_claimed(card_index) ||
_ct_bs->is_card_deferred(card_index),
"Card is either clean, claimed or deferred");
if (_ct_bs->claim_card(card_index))
scanCard(card_index, card_region);
}
if (!card_region->is_on_dirty_cards_region_list()) {
_g1h->push_dirty_cards_region(card_region);
}
// If the card is dirty, then we will scan it during updateRS.
if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) {
if (!_ct_bs->is_card_claimed(card_index) && _ct_bs->claim_card(card_index)) {
scanCard(card_index, card_region);
} else if (_try_claimed) {
if (jump_to_card == 0 || jump_to_card != current_card) {
// We did some useful work in the previous iteration.
// Decrease the distance.
skip_distance = MAX2(skip_distance >> 1, _min_skip_distance);
} else {
// Previous iteration resulted in a claim failure.
// Increase the distance.
skip_distance = MIN2(skip_distance << 1, _max_skip_distance);
}
jump_to_card = current_card + skip_distance;
}
}
++current_card;
}
if (!_try_claimed) {
hrrs->set_iter_complete();
}
hrrs->set_iter_complete();
return false;
}
// Set all cards back to clean.
@ -335,30 +333,17 @@ void HRInto_G1RemSet::updateRS(int worker_i) {
double start = os::elapsedTime();
_g1p->record_update_rs_start_time(worker_i, start * 1000.0);
if (G1RSBarrierUseQueue && !cg1r->do_traversal()) {
// Apply the appropriate closure to all remaining log entries.
_g1->iterate_dirty_card_closure(false, worker_i);
// Now there should be no dirty cards.
if (G1RSLogCheckCardTable) {
CountNonCleanMemRegionClosure cl(_g1);
_ct_bs->mod_card_iterate(&cl);
// XXX This isn't true any more: keeping cards of young regions
// marked dirty broke it. Need some reasonable fix.
guarantee(cl.n() == 0, "Card table should be clean.");
}
} else {
UpdateRSOutOfRegionClosure update_rs(_g1, worker_i);
_g1->heap_region_iterate(&update_rs);
// We did a traversal; no further one is necessary.
if (G1RSBarrierUseQueue) {
assert(cg1r->do_traversal(), "Or we shouldn't have gotten here.");
cg1r->set_pya_cancel();
}
if (_cg1r->use_cache()) {
_cg1r->clear_and_record_card_counts();
_cg1r->clear_hot_cache();
}
// Apply the appropriate closure to all remaining log entries.
_g1->iterate_dirty_card_closure(false, worker_i);
// Now there should be no dirty cards.
if (G1RSLogCheckCardTable) {
CountNonCleanMemRegionClosure cl(_g1);
_ct_bs->mod_card_iterate(&cl);
// XXX This isn't true any more: keeping cards of young regions
// marked dirty broke it. Need some reasonable fix.
guarantee(cl.n() == 0, "Card table should be clean.");
}
_g1p->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
}
@ -471,11 +456,6 @@ HRInto_G1RemSet::scanNewRefsRS(OopsInHeapRegionClosure* oc,
* 1000.0);
}
void HRInto_G1RemSet::set_par_traversal(bool b) {
_par_traversal_in_progress = b;
HeapRegionRemSet::set_par_traversal(b);
}
void HRInto_G1RemSet::cleanupHRRS() {
HeapRegionRemSet::cleanup();
}
@ -508,19 +488,19 @@ HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
// and they are causing failures. When we resolve said race
// conditions, we'll revert back to parallel remembered set
// updating and scanning. See CRs 6677707 and 6677708.
if (G1EnableParallelRSetUpdating || (worker_i == 0)) {
if (G1ParallelRSetUpdatingEnabled || (worker_i == 0)) {
updateRS(worker_i);
scanNewRefsRS(oc, worker_i);
} else {
_g1p->record_update_rs_start_time(worker_i, os::elapsedTime());
_g1p->record_update_rs_start_time(worker_i, os::elapsedTime() * 1000.0);
_g1p->record_update_rs_processed_buffers(worker_i, 0.0);
_g1p->record_update_rs_time(worker_i, 0.0);
_g1p->record_scan_new_refs_time(worker_i, 0.0);
}
if (G1EnableParallelRSetScanning || (worker_i == 0)) {
if (G1ParallelRSetScanningEnabled || (worker_i == 0)) {
scanRS(oc, worker_i);
} else {
_g1p->record_scan_rs_start_time(worker_i, os::elapsedTime());
_g1p->record_scan_rs_start_time(worker_i, os::elapsedTime() * 1000.0);
_g1p->record_scan_rs_time(worker_i, 0.0);
}
} else {
@ -547,11 +527,6 @@ prepare_for_oops_into_collection_set_do() {
if (ParallelGCThreads > 0) {
set_par_traversal(true);
_seq_task->set_par_threads((int)n_workers());
if (cg1r->do_traversal()) {
updateRS(0);
// Have to do this again after updaters
cleanupHRRS();
}
}
guarantee( _cards_scanned == NULL, "invariant" );
_cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers());
@ -632,11 +607,8 @@ void HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do() {
_g1->collection_set_iterate(&iterClosure);
// Set all cards back to clean.
_g1->cleanUpCardTable();
if (ParallelGCThreads > 0) {
ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine();
if (cg1r->do_traversal()) {
cg1r->cg1rThread()->set_do_traversal(false);
}
set_par_traversal(false);
}
@ -706,139 +678,8 @@ void HRInto_G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
}
class ConcRefineRegionClosure: public HeapRegionClosure {
G1CollectedHeap* _g1h;
CardTableModRefBS* _ctbs;
ConcurrentGCThread* _cgc_thrd;
ConcurrentG1Refine* _cg1r;
unsigned _cards_processed;
UpdateRSOopClosure _update_rs_oop_cl;
public:
ConcRefineRegionClosure(CardTableModRefBS* ctbs,
ConcurrentG1Refine* cg1r,
HRInto_G1RemSet* g1rs) :
_ctbs(ctbs), _cg1r(cg1r), _cgc_thrd(cg1r->cg1rThread()),
_update_rs_oop_cl(g1rs), _cards_processed(0),
_g1h(G1CollectedHeap::heap())
{}
bool doHeapRegion(HeapRegion* r) {
if (!r->in_collection_set() &&
!r->continuesHumongous() &&
!r->is_young()) {
_update_rs_oop_cl.set_from(r);
UpdateRSObjectClosure update_rs_obj_cl(&_update_rs_oop_cl);
// For each run of dirty card in the region:
// 1) Clear the cards.
// 2) Process the range corresponding to the run, adding any
// necessary RS entries.
// 1 must precede 2, so that a concurrent modification redirties the
// card. If a processing attempt does not succeed, because it runs
// into an unparseable region, we will do binary search to find the
// beginning of the next parseable region.
HeapWord* startAddr = r->bottom();
HeapWord* endAddr = r->used_region().end();
HeapWord* lastAddr;
HeapWord* nextAddr;
for (nextAddr = lastAddr = startAddr;
nextAddr < endAddr;
nextAddr = lastAddr) {
MemRegion dirtyRegion;
// Get and clear dirty region from card table
MemRegion next_mr(nextAddr, endAddr);
dirtyRegion =
_ctbs->dirty_card_range_after_reset(
next_mr,
true, CardTableModRefBS::clean_card_val());
assert(dirtyRegion.start() >= nextAddr,
"returned region inconsistent?");
if (!dirtyRegion.is_empty()) {
HeapWord* stop_point =
r->object_iterate_mem_careful(dirtyRegion,
&update_rs_obj_cl);
if (stop_point == NULL) {
lastAddr = dirtyRegion.end();
_cards_processed +=
(int) (dirtyRegion.word_size() / CardTableModRefBS::card_size_in_words);
} else {
// We're going to skip one or more cards that we can't parse.
HeapWord* next_parseable_card =
r->next_block_start_careful(stop_point);
// Round this up to a card boundary.
next_parseable_card =
_ctbs->addr_for(_ctbs->byte_after_const(next_parseable_card));
// Now we invalidate the intervening cards so we'll see them
// again.
MemRegion remaining_dirty =
MemRegion(stop_point, dirtyRegion.end());
MemRegion skipped =
MemRegion(stop_point, next_parseable_card);
_ctbs->invalidate(skipped.intersection(remaining_dirty));
// Now start up again where we can parse.
lastAddr = next_parseable_card;
// Count how many we did completely.
_cards_processed +=
(stop_point - dirtyRegion.start()) /
CardTableModRefBS::card_size_in_words;
}
// Allow interruption at regular intervals.
// (Might need to make them more regular, if we get big
// dirty regions.)
if (_cgc_thrd != NULL) {
if (_cgc_thrd->should_yield()) {
_cgc_thrd->yield();
switch (_cg1r->get_pya()) {
case PYA_continue:
// This may have changed: re-read.
endAddr = r->used_region().end();
continue;
case PYA_restart: case PYA_cancel:
return true;
}
}
}
} else {
break;
}
}
}
// A good yield opportunity.
if (_cgc_thrd != NULL) {
if (_cgc_thrd->should_yield()) {
_cgc_thrd->yield();
switch (_cg1r->get_pya()) {
case PYA_restart: case PYA_cancel:
return true;
default:
break;
}
}
}
return false;
}
unsigned cards_processed() { return _cards_processed; }
};
void HRInto_G1RemSet::concurrentRefinementPass(ConcurrentG1Refine* cg1r) {
ConcRefineRegionClosure cr_cl(ct_bs(), cg1r, this);
_g1->heap_region_iterate(&cr_cl);
_conc_refine_traversals++;
_conc_refine_cards += cr_cl.cards_processed();
}
static IntHistogram out_of_histo(50, 50);
void HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i) {
// If the card is no longer dirty, nothing to do.
if (*card_ptr != CardTableModRefBS::dirty_card_val()) return;
@ -968,10 +809,16 @@ public:
HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
};
class PrintRSThreadVTimeClosure : public ThreadClosure {
public:
virtual void do_thread(Thread *t) {
ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
gclog_or_tty->print(" %5.2f", crt->vtime_accum());
}
};
void HRInto_G1RemSet::print_summary_info() {
G1CollectedHeap* g1 = G1CollectedHeap::heap();
ConcurrentG1RefineThread* cg1r_thrd =
g1->concurrent_g1_refine()->cg1rThread();
#if CARD_REPEAT_HISTO
gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
@ -984,15 +831,13 @@ void HRInto_G1RemSet::print_summary_info() {
gclog_or_tty->print_cr(" # of CS ptrs --> # of cards with that number.");
out_of_histo.print_on(gclog_or_tty);
}
gclog_or_tty->print_cr("\n Concurrent RS processed %d cards in "
"%5.2fs.",
_conc_refine_cards, cg1r_thrd->vtime_accum());
gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
_conc_refine_cards);
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
jint tot_processed_buffers =
dcqs.processed_buffers_mut() + dcqs.processed_buffers_rs_thread();
gclog_or_tty->print_cr(" Of %d completed buffers:", tot_processed_buffers);
gclog_or_tty->print_cr(" %8d (%5.1f%%) by conc RS thread.",
gclog_or_tty->print_cr(" %8d (%5.1f%%) by conc RS threads.",
dcqs.processed_buffers_rs_thread(),
100.0*(float)dcqs.processed_buffers_rs_thread()/
(float)tot_processed_buffers);
@ -1000,15 +845,12 @@ void HRInto_G1RemSet::print_summary_info() {
dcqs.processed_buffers_mut(),
100.0*(float)dcqs.processed_buffers_mut()/
(float)tot_processed_buffers);
gclog_or_tty->print_cr(" Did %d concurrent refinement traversals.",
_conc_refine_traversals);
if (!G1RSBarrierUseQueue) {
gclog_or_tty->print_cr(" Scanned %8.2f cards/traversal.",
_conc_refine_traversals > 0 ?
(float)_conc_refine_cards/(float)_conc_refine_traversals :
0);
}
gclog_or_tty->print_cr(" Conc RS threads times(s)");
PrintRSThreadVTimeClosure p;
gclog_or_tty->print(" ");
g1->concurrent_g1_refine()->threads_do(&p);
gclog_or_tty->print_cr("");
if (G1UseHRIntoRS) {
HRRSStatsIter blk;
g1->heap_region_iterate(&blk);

View File

@ -33,15 +33,12 @@ class ConcurrentG1Refine;
class G1RemSet: public CHeapObj {
protected:
G1CollectedHeap* _g1;
unsigned _conc_refine_traversals;
unsigned _conc_refine_cards;
size_t n_workers();
public:
G1RemSet(G1CollectedHeap* g1) :
_g1(g1), _conc_refine_traversals(0), _conc_refine_cards(0)
_g1(g1), _conc_refine_cards(0)
{}
// Invoke "blk->do_oop" on all pointers into the CS in object in regions
@ -81,19 +78,11 @@ public:
virtual void scrub_par(BitMap* region_bm, BitMap* card_bm,
int worker_num, int claim_val) = 0;
// Do any "refinement" activity that might be appropriate to the given
// G1RemSet. If "refinement" has iterateive "passes", do one pass.
// If "t" is non-NULL, it is the thread performing the refinement.
// Default implementation does nothing.
virtual void concurrentRefinementPass(ConcurrentG1Refine* cg1r) {}
// Refine the card corresponding to "card_ptr". If "sts" is non-NULL,
// join and leave around parts that must be atomic wrt GC. (NULL means
// being done at a safepoint.)
virtual void concurrentRefineOneCard(jbyte* card_ptr, int worker_i) {}
unsigned conc_refine_cards() { return _conc_refine_cards; }
// Print any relevant summary info.
virtual void print_summary_info() {}
@ -153,7 +142,7 @@ protected:
// progress. If so, then cards added to remembered sets should also have
// their references into the collection summarized in "_new_refs".
bool _par_traversal_in_progress;
void set_par_traversal(bool b);
void set_par_traversal(bool b) { _par_traversal_in_progress = b; }
GrowableArray<oop*>** _new_refs;
void new_refs_iterate(OopClosure* cl);
@ -194,7 +183,6 @@ public:
void scrub_par(BitMap* region_bm, BitMap* card_bm,
int worker_num, int claim_val);
virtual void concurrentRefinementPass(ConcurrentG1Refine* t);
virtual void concurrentRefineOneCard(jbyte* card_ptr, int worker_i);
virtual void print_summary_info();

View File

@ -28,87 +28,65 @@
#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
\
product(intx, ParallelGCG1AllocBufferSize, 8*K, \
product(intx, G1ParallelGCAllocBufferSize, 8*K, \
"Size of parallel G1 allocation buffers in to-space.") \
\
product(intx, G1TimeSliceMS, 500, \
"Time slice for MMU specification") \
\
product(intx, G1MaxPauseTimeMS, 200, \
"Max GC time per MMU time slice") \
\
product(intx, G1ConfidencePerc, 50, \
product(intx, G1ConfidencePercent, 50, \
"Confidence level for MMU/pause predictions") \
\
product(intx, G1MarkingOverheadPerc, 0, \
develop(intx, G1MarkingOverheadPercent, 0, \
"Overhead of concurrent marking") \
\
product(bool, G1AccountConcurrentOverhead, false, \
develop(bool, G1AccountConcurrentOverhead, false, \
"Whether soft real-time compliance in G1 will take into account" \
"concurrent overhead") \
\
product(intx, G1YoungGenSize, 0, \
"Size of the G1 young generation, 0 is the adaptive policy") \
\
product(bool, G1Gen, true, \
develop(bool, G1Gen, true, \
"If true, it will enable the generational G1") \
\
develop(intx, G1GCPct, 10, \
develop(intx, G1GCPercent, 10, \
"The desired percent time spent on GC") \
\
product(intx, G1PolicyVerbose, 0, \
develop(intx, G1PolicyVerbose, 0, \
"The verbosity level on G1 policy decisions") \
\
develop(bool, G1UseHRIntoRS, true, \
"Determines whether the 'advanced' HR Into rem set is used.") \
\
product(bool, G1VerifyRemSet, false, \
"If true, verify the rem set functioning at each GC") \
\
product(bool, G1VerifyConcMark, false, \
"If true, verify the conc marking code at full GC time") \
\
develop(intx, G1MarkingVerboseLevel, 0, \
"Level (0-4) of verboseness of the marking code") \
\
develop(bool, G1VerifyConcMarkPrintReachable, true, \
develop(bool, G1VerifyConcMarkPrintReachable, false, \
"If conc mark verification fails, print reachable objects") \
\
develop(bool, G1TraceMarkStackOverflow, false, \
"If true, extra debugging code for CM restart for ovflw.") \
\
product(bool, G1VerifyMarkingInEvac, false, \
"If true, verify marking info during evacuation") \
\
develop(intx, G1PausesBtwnConcMark, -1, \
"If positive, fixed number of pauses between conc markings") \
\
product(intx, G1EfficiencyPctCausesMark, 80, \
"The cum gc efficiency since mark fall-off that causes " \
"new marking") \
\
product(bool, TraceConcurrentMark, false, \
"Trace concurrent mark") \
\
product(bool, SummarizeG1ConcMark, false, \
diagnostic(bool, G1SummarizeConcurrentMark, false, \
"Summarize concurrent mark info") \
\
product(bool, SummarizeG1RSStats, false, \
diagnostic(bool, G1SummarizeRSetStats, false, \
"Summarize remembered set processing info") \
\
product(bool, SummarizeG1ZFStats, false, \
diagnostic(bool, G1SummarizeZFStats, false, \
"Summarize zero-filling info") \
\
product(bool, TraceG1Refine, false, \
develop(bool, G1TraceConcurrentRefinement, false, \
"Trace G1 concurrent refinement") \
\
develop(bool, G1ConcMark, true, \
"If true, run concurrent marking for G1") \
\
product(intx, G1CMStackSize, 2 * 1024 * 1024, \
product(intx, G1MarkStackSize, 2 * 1024 * 1024, \
"Size of the mark stack for concurrent marking.") \
\
product(intx, G1CMRegionStackSize, 1024 * 1024, \
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
"Size of the region stack for concurrent marking.") \
\
develop(bool, G1ConcRefine, true, \
@ -121,7 +99,7 @@
"Number of heap regions of alloc ahead of starting collection " \
"pause to start concurrent refinement (initially)") \
\
product(bool, G1SmoothConcRefine, true, \
develop(bool, G1SmoothConcRefine, true, \
"Attempts to smooth out the overhead of concurrent refinement") \
\
develop(bool, G1ConcZeroFill, true, \
@ -157,7 +135,7 @@
develop(bool, G1SATBPrintStubs, false, \
"If true, print generated stubs for the SATB barrier") \
\
product(intx, G1ExpandByPctOfAvail, 20, \
product(intx, G1ExpandByPercentOfAvailable, 20, \
"When expanding, % of uncommitted space to claim.") \
\
develop(bool, G1RSBarrierRegionFilter, true, \
@ -169,9 +147,6 @@
develop(bool, G1PrintCTFilterStats, false, \
"If true, print stats on RS filtering effectiveness") \
\
develop(bool, G1RSBarrierUseQueue, true, \
"If true, use queueing RS barrier") \
\
develop(bool, G1DeferredRSUpdate, true, \
"If true, use deferred RS updates") \
\
@ -179,18 +154,9 @@
"If true, verify that no dirty cards remain after RS log " \
"processing.") \
\
product(intx, G1MinPausesBetweenMarks, 2, \
"Number of inefficient pauses necessary to trigger marking.") \
\
product(intx, G1InefficientPausePct, 80, \
"Threshold of an 'inefficient' pauses (as % of cum efficiency.") \
\
develop(bool, G1RSCountHisto, false, \
"If true, print a histogram of RS occupancies after each pause") \
\
product(bool, G1TraceFileOverwrite, false, \
"Allow the trace file to be overwritten") \
\
develop(intx, G1PrintRegionLivenessInfo, 0, \
"When > 0, print the occupancies of the <n> best and worst" \
"regions.") \
@ -198,9 +164,6 @@
develop(bool, G1PrintParCleanupStats, false, \
"When true, print extra stats about parallel cleanup.") \
\
product(bool, G1DoAgeCohortChecks, false, \
"When true, check well-formedness of age cohort structures.") \
\
develop(bool, G1DisablePreBarrier, false, \
"Disable generation of pre-barrier (i.e., marking barrier) ") \
\
@ -214,17 +177,17 @@
develop(intx, G1ConcRSLogCacheSize, 10, \
"Log base 2 of the length of conc RS hot-card cache.") \
\
product(bool, G1ConcRSCountTraversals, false, \
develop(bool, G1ConcRSCountTraversals, false, \
"If true, gather data about the number of times CR traverses " \
"cards ") \
\
product(intx, G1ConcRSHotCardLimit, 4, \
develop(intx, G1ConcRSHotCardLimit, 4, \
"The threshold that defines (>=) a hot card.") \
\
develop(bool, G1PrintOopAppls, false, \
"When true, print applications of closures to external locs.") \
\
product(intx, G1LogRSRegionEntries, 7, \
develop(intx, G1LogRSRegionEntries, 7, \
"Log_2 of max number of regions for which we keep bitmaps.") \
\
develop(bool, G1RecordHRRSOops, false, \
@ -254,11 +217,11 @@
"It determines whether the system will calculate an optimum " \
"scan-only set.") \
\
product(intx, G1MinReservePerc, 10, \
product(intx, G1MinReservePercent, 10, \
"It determines the minimum reserve we should have in the heap " \
"to minimize the probability of promotion failure.") \
\
product(bool, G1TraceRegions, false, \
diagnostic(bool, G1PrintRegions, false, \
"If set G1 will print information on which regions are being " \
"allocated and which are reclaimed.") \
\
@ -268,25 +231,29 @@
develop(bool, G1HRRSFlushLogBuffersOnVerify, false, \
"Forces flushing of log buffers before verification.") \
\
product(bool, G1UseSurvivorSpace, true, \
product(bool, G1UseSurvivorSpaces, true, \
"When true, use survivor space.") \
\
product(bool, G1FixedTenuringThreshold, false, \
develop(bool, G1FixedTenuringThreshold, false, \
"When set, G1 will not adjust the tenuring threshold") \
\
product(bool, G1FixedEdenSize, false, \
develop(bool, G1FixedEdenSize, false, \
"When set, G1 will not allocate unused survivor space regions") \
\
product(uintx, G1FixedSurvivorSpaceSize, 0, \
develop(uintx, G1FixedSurvivorSpaceSize, 0, \
"If non-0 is the size of the G1 survivor space, " \
"otherwise SurvivorRatio is used to determine the size") \
\
experimental(bool, G1EnableParallelRSetUpdating, false, \
experimental(bool, G1ParallelRSetUpdatingEnabled, false, \
"Enables the parallelization of remembered set updating " \
"during evacuation pauses") \
\
experimental(bool, G1EnableParallelRSetScanning, false, \
experimental(bool, G1ParallelRSetScanningEnabled, false, \
"Enables the parallelization of remembered set scanning " \
"during evacuation pauses")
"during evacuation pauses") \
\
product(uintx, G1ParallelRSetThreads, 0, \
"If non-0 is the number of parallel rem set update threads, " \
"otherwise the value is determined ergonomically.")
G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)

View File

@ -160,12 +160,6 @@ HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
if (!g1h->is_obj_dead(cur_oop, hr)) {
// Bottom lies entirely below top, so we can call the
// non-memRegion version of oop_iterate below.
#ifndef PRODUCT
if (G1VerifyMarkingInEvac) {
VerifyLiveClosure vl_cl(g1h);
cur_oop->oop_iterate(&vl_cl);
}
#endif
cur_oop->oop_iterate(cl);
}
cur = next_obj;
@ -197,12 +191,6 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
// or it was allocated after marking finished, then we add it. Otherwise
// we can safely ignore the object.
if (!g1h->is_obj_dead(oop(bottom), _hr)) {
#ifndef PRODUCT
if (G1VerifyMarkingInEvac) {
VerifyLiveClosure vl_cl(g1h);
oop(bottom)->oop_iterate(&vl_cl, mr);
}
#endif
oop_size = oop(bottom)->oop_iterate(cl2, mr);
} else {
oop_size = oop(bottom)->size();
@ -232,12 +220,6 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
// Last object. Need to do dead-obj filtering here too.
if (!g1h->is_obj_dead(oop(bottom), _hr)) {
#ifndef PRODUCT
if (G1VerifyMarkingInEvac) {
VerifyLiveClosure vl_cl(g1h);
oop(bottom)->oop_iterate(&vl_cl, mr);
}
#endif
oop(bottom)->oop_iterate(cl2, mr);
}
}
@ -369,6 +351,7 @@ HeapRegion(G1BlockOffsetSharedArray* sharedOffsetArray,
_claimed(InitialClaimValue), _evacuation_failed(false),
_prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1),
_young_type(NotYoung), _next_young_region(NULL),
_next_dirty_cards_region(NULL),
_young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1),
_rem_set(NULL), _zfs(NotZeroFilled)
{
@ -713,12 +696,12 @@ void HeapRegion::verify(bool allow_dirty) const {
G1CollectedHeap::heap()->print();
gclog_or_tty->print_cr("");
}
if (G1VerifyConcMark &&
if (VerifyDuringGC &&
G1VerifyConcMarkPrintReachable &&
vl_cl.failures()) {
g1->concurrent_mark()->print_prev_bitmap_reachable();
}
guarantee(!vl_cl.failures(), "should not have had any failures");
guarantee(!vl_cl.failures(), "region verification failed");
guarantee(p == top(), "end of last object must match end of space");
}

View File

@ -227,6 +227,9 @@ class HeapRegion: public G1OffsetTableContigSpace {
// next region in the young "generation" region set
HeapRegion* _next_young_region;
// Next region whose cards need cleaning
HeapRegion* _next_dirty_cards_region;
// For parallel heapRegion traversal.
jint _claimed;
@ -468,6 +471,11 @@ class HeapRegion: public G1OffsetTableContigSpace {
_next_young_region = hr;
}
HeapRegion* get_next_dirty_cards_region() const { return _next_dirty_cards_region; }
HeapRegion** next_dirty_cards_region_addr() { return &_next_dirty_cards_region; }
void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; }
bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; }
// Allows logical separation between objects allocated before and after.
void save_marks();

View File

@ -1052,18 +1052,11 @@ bool OtherRegionsTable::contains_reference_locked(oop* from) const {
}
bool HeapRegionRemSet::_par_traversal = false;
void HeapRegionRemSet::set_par_traversal(bool b) {
assert(_par_traversal != b, "Proper alternation...");
_par_traversal = b;
}
// Determines how many threads can add records to an rset in parallel.
// This can be done by either mutator threads together with the
// concurrent refinement threads or GC threads.
int HeapRegionRemSet::num_par_rem_sets() {
// We always have at least two, so that a mutator thread can claim an
// id and add to a rem set.
return (int) MAX2(ParallelGCThreads, (size_t)2);
return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
}
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,

View File

@ -177,8 +177,6 @@ private:
G1BlockOffsetSharedArray* _bosa;
G1BlockOffsetSharedArray* bosa() const { return _bosa; }
static bool _par_traversal;
OtherRegionsTable _other_regions;
// One set bit for every region that has an entry for this one.
@ -211,8 +209,6 @@ public:
HeapRegion* hr);
static int num_par_rem_sets();
static bool par_traversal() { return _par_traversal; }
static void set_par_traversal(bool b);
HeapRegion* hr() const {
return _other_regions.hr();

View File

@ -172,7 +172,7 @@ void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index, bool ignore_
_n_completed_buffers++;
if (!_process_completed &&
_n_completed_buffers == _process_completed_threshold) {
_n_completed_buffers >= _process_completed_threshold) {
_process_completed = true;
if (_notify_when_complete)
_cbl_mon->notify_all();

View File

@ -49,6 +49,8 @@ concurrentG1Refine.cpp space.inline.hpp
concurrentG1Refine.hpp globalDefinitions.hpp
concurrentG1Refine.hpp allocation.hpp
concurrentG1Refine.hpp thread.hpp
concurrentG1RefineThread.cpp concurrentG1Refine.hpp
concurrentG1RefineThread.cpp concurrentG1RefineThread.hpp
@ -280,6 +282,7 @@ heapRegionRemSet.hpp sparsePRT.hpp
heapRegionRemSet.cpp allocation.hpp
heapRegionRemSet.cpp bitMap.inline.hpp
heapRegionRemSet.cpp concurrentG1Refine.hpp
heapRegionRemSet.cpp g1BlockOffsetTable.inline.hpp
heapRegionRemSet.cpp g1CollectedHeap.inline.hpp
heapRegionRemSet.cpp heapRegionRemSet.hpp

View File

@ -27,13 +27,12 @@
# include "incls/_precompiled.incl"
# include "incls/_concurrentGCThread.cpp.incl"
bool ConcurrentGCThread::_should_terminate = false;
bool ConcurrentGCThread::_has_terminated = false;
int ConcurrentGCThread::_CGC_flag = CGC_nil;
SuspendibleThreadSet ConcurrentGCThread::_sts;
ConcurrentGCThread::ConcurrentGCThread() {
ConcurrentGCThread::ConcurrentGCThread() :
_should_terminate(false), _has_terminated(false) {
_sts.initialize();
};

View File

@ -72,8 +72,8 @@ class ConcurrentGCThread: public NamedThread {
friend class VMStructs;
protected:
static bool _should_terminate;
static bool _has_terminated;
bool _should_terminate;
bool _has_terminated;
enum CGC_flag_type {
CGC_nil = 0x0,

View File

@ -33,12 +33,8 @@ CardTableRS::CardTableRS(MemRegion whole_heap,
{
#ifndef SERIALGC
if (UseG1GC) {
if (G1RSBarrierUseQueue) {
_ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
max_covered_regions);
} else {
_ct_bs = new G1SATBCardTableModRefBS(whole_heap, max_covered_regions);
}
} else {
_ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
}

View File

@ -1181,7 +1181,28 @@ int constantPoolOopDesc::copy_cpool_bytes(int cpool_size,
unsigned int hash;
char *str = string_at_noresolve(idx);
symbolOop sym = SymbolTable::lookup_only(str, (int) strlen(str), hash);
idx1 = tbl->symbol_to_value(sym);
if (sym == NULL) {
// sym can be NULL if string refers to incorrectly encoded JVM_CONSTANT_Utf8
// this can happen with JVM TI; see CR 6839599 for more details
oop string = *(obj_at_addr(idx));
assert(java_lang_String::is_instance(string),"Not a String");
DBG(printf("Error #%03hd tag=%03hd\n", idx, tag));
idx1 = 0;
for (int j = 0; j < tbl->table_size() && idx1 == 0; j++) {
for (SymbolHashMapEntry* cur = tbl->bucket(j); cur != NULL; cur = cur->next()) {
int length;
sym = cur->symbol();
jchar* chars = sym->as_unicode(length);
if (java_lang_String::equals(string, chars, length)) {
idx1 = cur->value();
DBG(printf("Index found: %d\n",idx1));
break;
}
}
}
} else {
idx1 = tbl->symbol_to_value(sym);
}
assert(idx1 != 0, "Have not found a hashtable entry");
Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, str));

View File

@ -104,6 +104,10 @@ macro(ConvL2I)
macro(CosD)
macro(CountedLoop)
macro(CountedLoopEnd)
macro(CountLeadingZerosI)
macro(CountLeadingZerosL)
macro(CountTrailingZerosI)
macro(CountTrailingZerosL)
macro(CreateEx)
macro(DecodeN)
macro(DivD)

View File

@ -128,6 +128,10 @@ Node *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f
// Swapped Cmp is OK
(phase->eqv(cmp->in(2),f) &&
phase->eqv(cmp->in(1),t)) ) {
// Give up this identity check for floating points because it may choose incorrect
// value around 0.0 and -0.0
if ( cmp->Opcode()==Op_CmpF || cmp->Opcode()==Op_CmpD )
return NULL;
// Check for "(t==f)?t:f;" and replace with "f"
if( b->_test._test == BoolTest::eq )
return f;
@ -1251,3 +1255,93 @@ const Type *MoveD2LNode::Value( PhaseTransform *phase ) const {
v.set_jdouble(td->getd());
return TypeLong::make( v.get_jlong() );
}
//------------------------------Value------------------------------------------
const Type* CountLeadingZerosINode::Value(PhaseTransform* phase) const {
const Type* t = phase->type(in(1));
if (t == Type::TOP) return Type::TOP;
const TypeInt* ti = t->isa_int();
if (ti && ti->is_con()) {
jint i = ti->get_con();
// HD, Figure 5-6
if (i == 0)
return TypeInt::make(BitsPerInt);
int n = 1;
unsigned int x = i;
if (x >> 16 == 0) { n += 16; x <<= 16; }
if (x >> 24 == 0) { n += 8; x <<= 8; }
if (x >> 28 == 0) { n += 4; x <<= 4; }
if (x >> 30 == 0) { n += 2; x <<= 2; }
n -= x >> 31;
return TypeInt::make(n);
}
return TypeInt::INT;
}
//------------------------------Value------------------------------------------
const Type* CountLeadingZerosLNode::Value(PhaseTransform* phase) const {
const Type* t = phase->type(in(1));
if (t == Type::TOP) return Type::TOP;
const TypeLong* tl = t->isa_long();
if (tl && tl->is_con()) {
jlong l = tl->get_con();
// HD, Figure 5-6
if (l == 0)
return TypeInt::make(BitsPerLong);
int n = 1;
unsigned int x = (((julong) l) >> 32);
if (x == 0) { n += 32; x = (int) l; }
if (x >> 16 == 0) { n += 16; x <<= 16; }
if (x >> 24 == 0) { n += 8; x <<= 8; }
if (x >> 28 == 0) { n += 4; x <<= 4; }
if (x >> 30 == 0) { n += 2; x <<= 2; }
n -= x >> 31;
return TypeInt::make(n);
}
return TypeInt::INT;
}
//------------------------------Value------------------------------------------
const Type* CountTrailingZerosINode::Value(PhaseTransform* phase) const {
const Type* t = phase->type(in(1));
if (t == Type::TOP) return Type::TOP;
const TypeInt* ti = t->isa_int();
if (ti && ti->is_con()) {
jint i = ti->get_con();
// HD, Figure 5-14
int y;
if (i == 0)
return TypeInt::make(BitsPerInt);
int n = 31;
y = i << 16; if (y != 0) { n = n - 16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
y = i << 1; if (y != 0) { n = n - 1; }
return TypeInt::make(n);
}
return TypeInt::INT;
}
//------------------------------Value------------------------------------------
const Type* CountTrailingZerosLNode::Value(PhaseTransform* phase) const {
const Type* t = phase->type(in(1));
if (t == Type::TOP) return Type::TOP;
const TypeLong* tl = t->isa_long();
if (tl && tl->is_con()) {
jlong l = tl->get_con();
// HD, Figure 5-14
int x, y;
if (l == 0)
return TypeInt::make(BitsPerLong);
int n = 63;
y = (int) l; if (y != 0) { n = n - 32; x = y; } else x = (((julong) l) >> 32);
y = x << 16; if (y != 0) { n = n - 16; x = y; }
y = x << 8; if (y != 0) { n = n - 8; x = y; }
y = x << 4; if (y != 0) { n = n - 4; x = y; }
y = x << 2; if (y != 0) { n = n - 2; x = y; }
y = x << 1; if (y != 0) { n = n - 1; }
return TypeInt::make(n);
}
return TypeInt::INT;
}

View File

@ -636,22 +636,62 @@ class MoveD2LNode : public Node {
virtual const Type* Value( PhaseTransform *phase ) const;
};
//---------- PopCountINode -----------------------------------------------------
// Population count (bit count) of an integer.
class PopCountINode : public Node {
//---------- CountBitsNode -----------------------------------------------------
class CountBitsNode : public Node {
public:
PopCountINode(Node* in1) : Node(0, in1) {}
virtual int Opcode() const;
CountBitsNode(Node* in1) : Node(0, in1) {}
const Type* bottom_type() const { return TypeInt::INT; }
virtual uint ideal_reg() const { return Op_RegI; }
};
//---------- CountLeadingZerosINode --------------------------------------------
// Count leading zeros (0-bit count starting from MSB) of an integer.
class CountLeadingZerosINode : public CountBitsNode {
public:
CountLeadingZerosINode(Node* in1) : CountBitsNode(in1) {}
virtual int Opcode() const;
virtual const Type* Value(PhaseTransform* phase) const;
};
//---------- CountLeadingZerosLNode --------------------------------------------
// Count leading zeros (0-bit count starting from MSB) of a long.
class CountLeadingZerosLNode : public CountBitsNode {
public:
CountLeadingZerosLNode(Node* in1) : CountBitsNode(in1) {}
virtual int Opcode() const;
virtual const Type* Value(PhaseTransform* phase) const;
};
//---------- CountTrailingZerosINode -------------------------------------------
// Count trailing zeros (0-bit count starting from LSB) of an integer.
class CountTrailingZerosINode : public CountBitsNode {
public:
CountTrailingZerosINode(Node* in1) : CountBitsNode(in1) {}
virtual int Opcode() const;
virtual const Type* Value(PhaseTransform* phase) const;
};
//---------- CountTrailingZerosLNode -------------------------------------------
// Count trailing zeros (0-bit count starting from LSB) of a long.
class CountTrailingZerosLNode : public CountBitsNode {
public:
CountTrailingZerosLNode(Node* in1) : CountBitsNode(in1) {}
virtual int Opcode() const;
virtual const Type* Value(PhaseTransform* phase) const;
};
//---------- PopCountINode -----------------------------------------------------
// Population count (bit count) of an integer.
class PopCountINode : public CountBitsNode {
public:
PopCountINode(Node* in1) : CountBitsNode(in1) {}
virtual int Opcode() const;
};
//---------- PopCountLNode -----------------------------------------------------
// Population count (bit count) of a long.
class PopCountLNode : public Node {
class PopCountLNode : public CountBitsNode {
public:
PopCountLNode(Node* in1) : Node(0, in1) {}
PopCountLNode(Node* in1) : CountBitsNode(in1) {}
virtual int Opcode() const;
const Type* bottom_type() const { return TypeInt::INT; }
virtual uint ideal_reg() const { return Op_RegI; }
};

View File

@ -298,8 +298,10 @@ static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_con
// 6732154: Construct both w1 and w2 before transforming, so t
// doesn't go dead prematurely.
w1 = phase->transform(w1);
// 6837011: We need to transform w2 before w1 because the
// transformation of w1 could return t.
w2 = phase->transform(w2);
w1 = phase->transform(w1);
// w1 = u0*v1 + w1;
Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1));

View File

@ -47,7 +47,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
CallGenerator* cg;
// Dtrace currently doesn't work unless all calls are vanilla
if (DTraceMethodProbes) {
if (env()->dtrace_method_probes()) {
allow_inline = false;
}

View File

@ -905,15 +905,22 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
// see if it is unescaped.
if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable)
continue;
if (alloc->is_Allocate()) {
// Set the scalar_replaceable flag before the next check.
alloc->as_Allocate()->_is_scalar_replaceable = true;
}
// find CheckCastPP of call return value
// Find CheckCastPP for the allocate or for the return value of a call
n = alloc->result_cast();
if (n == NULL || // No uses accept Initialize or
!n->is_CheckCastPP()) // not unique CheckCastPP.
if (n == NULL) { // No uses except Initialize node
if (alloc->is_Allocate()) {
// Set the scalar_replaceable flag for allocation
// so it could be eliminated if it has no uses.
alloc->as_Allocate()->_is_scalar_replaceable = true;
}
continue;
}
if (!n->is_CheckCastPP()) { // not unique CheckCastPP.
assert(!alloc->is_Allocate(), "allocation should have unique type");
continue;
}
// The inline code for Object.clone() casts the allocation result to
// java.lang.Object and then to the actual type of the allocated
// object. Detect this case and use the second cast.
@ -934,9 +941,17 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
if (cast2 != NULL) {
n = cast2;
} else {
// Non-scalar replaceable if the allocation type is unknown statically
// (reflection allocation), the object can't be restored during
// deoptimization without precise type.
continue;
}
}
if (alloc->is_Allocate()) {
// Set the scalar_replaceable flag for allocation
// so it could be eliminated.
alloc->as_Allocate()->_is_scalar_replaceable = true;
}
set_escape_state(n->_idx, es);
// in order for an object to be scalar-replaceable, it must be:
// - a direct allocation (not a call returning an object)

View File

@ -617,6 +617,9 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
assert(!LCA_orig->dominates(pred_block) ||
early->dominates(pred_block), "early is high enough");
must_raise_LCA = true;
} else {
// anti-dependent upon PHI pinned below 'early', no edge needed
LCA = early; // but can not schedule below 'early'
}
}
}

Some files were not shown because too many files have changed in this diff Show More