Merge
This commit is contained in:
commit
4f420274a7
6
.hgtags
6
.hgtags
@ -23,3 +23,9 @@ caf58ffa084568990cbb3441f9ae188e36b31770 jdk7-b42
|
||||
04b2620edc72de93671646e4720c5992c74ac8b5 jdk7-b46
|
||||
0c4657194eec95c08ba478aee9cfc3c295e41657 jdk7-b47
|
||||
1bf51a4c2627c2f0e0cbcc2cf0421bdb37f1f2b2 jdk7-b48
|
||||
6b84b04a80afe23262377c60913eebfc898f14c4 jdk7-b49
|
||||
5da0e6b9f4f18ef483c977337214b12ee0e1fc8f jdk7-b50
|
||||
a25c5ec5e40e07733d1ff9898a0abe36159288ff jdk7-b51
|
||||
7a90e89e36d103038f8667f6a7daae34ecfa1ad8 jdk7-b52
|
||||
d52186ee770dac57950536cd00ccbfdef360b04c jdk7-b53
|
||||
15096652c4d48dfb9fc0b2cb135304db94c65ba0 jdk7-b54
|
||||
|
@ -23,3 +23,9 @@ a395e3aac4744cc9033fcd819fad1239a45add52 jdk7-b44
|
||||
e8a2a4d187773a62f3309b0fa265c13425bc2258 jdk7-b46
|
||||
d7744e86dedc21a8ecf6bdb73eb191b8eaf5b0da jdk7-b47
|
||||
4ae9f4bfdb98f65bd957e3fe72471b320150b38e jdk7-b48
|
||||
aee93a8992d2389121eb610c00a86196f3e2b9b0 jdk7-b49
|
||||
5111e13e44e542fe945b47ab154546daec36737d jdk7-b50
|
||||
0f0189d55ce4a1f7840da7582ac7d970b3b7ab15 jdk7-b51
|
||||
4264c2fe66493e57c411045a1b61377796641e45 jdk7-b52
|
||||
c235f4a8559d196879c56af80159f67ee5d0e720 jdk7-b53
|
||||
2ef382b1bbd58a68e668391c6145a4b2066c5b96 jdk7-b54
|
||||
|
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1995-2009 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
|
||||
|
@ -23,3 +23,9 @@ ccd6a16502e0650d91d85c4b86be05cbcd461a87 jdk7-b42
|
||||
1691dbfc08f8ee3f4e23a1ff30cdff920718696c jdk7-b46
|
||||
167ad0164301f318b069a947e1c9c07ed667748a jdk7-b47
|
||||
0be222241fd405e48915647facfaa176621b39b9 jdk7-b48
|
||||
d70978bc64bc7a04be7797ab0dcd9b7b1b3a6bff jdk7-b49
|
||||
0edbd0074b02b42b2b83cc47cb391d4869b7a8ec jdk7-b50
|
||||
3eb8f1047a7402a9a79937d1c39560e931e91da2 jdk7-b51
|
||||
bec82237d694f9802b820fa11bbb4f7fa9bf8e77 jdk7-b52
|
||||
3c4d73194f6f89f040ae3b2d257335dfa8a1b2b5 jdk7-b53
|
||||
8130ac858d6789d5853d23044ba4a992afda574a jdk7-b54
|
||||
|
@ -112,8 +112,6 @@ ifndef TARGET_JAVA
|
||||
TARGET_JAVA = java
|
||||
endif
|
||||
|
||||
NO_PROPRIETARY_API_WARNINGS = -XDignore.symbol.file=true
|
||||
|
||||
SELF = $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
# for jdk, we generate the following:
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2002-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2002-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1997-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
@ -46,8 +46,6 @@ 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
|
||||
#
|
||||
@ -80,11 +78,11 @@ ORBUTIL.MC = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/ORBUtil.mc
|
||||
POA.MC = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/POA.mc
|
||||
UTIL.MC = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/Util.mc
|
||||
|
||||
MC_GENERATE_CLASS = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-class
|
||||
MC_GENERATE_LOG_RB = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-resource
|
||||
MC_GENERATE_CLASS = make-class
|
||||
MC_GENERATE_LOG_RB = make-resource
|
||||
|
||||
JSCHEME_GENERATE_CLASS = $(BOOT_JAVA_CMD) jscheme.REPL $(MC_GENERATE_CLASS)
|
||||
JSCHEME_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) jscheme.REPL $(MC_GENERATE_LOG_RB)
|
||||
JSCHEME_GENERATE_CLASS = $(BOOT_JAVA_CMD) com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_CLASS)
|
||||
JSCHEME_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_LOG_RB)
|
||||
|
||||
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1999-2009 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
|
||||
|
@ -191,14 +191,18 @@ $(JAVA_SOURCE_LIST) : source_list_prime resources $(FILES_class)
|
||||
# Make sure all newer sources are compiled (in a batch)
|
||||
classes : $(CLASSES_INIT) .delete.classlist .compile.classlist
|
||||
|
||||
# Use this javac option to force it to favor the sourcepath file classes
|
||||
# rather than any bootclasspath classes.
|
||||
JAVAC_PREFER_SOURCE = -Xprefer:source
|
||||
|
||||
.compile.classlist : $(JAVA_SOURCE_LIST)
|
||||
@$(MKDIR) -p $(CLASSDESTDIR)
|
||||
@if [ `$(CAT) $(JAVA_SOURCE_LIST) | $(WC) -l` -ge 1 ] ; then \
|
||||
$(ECHO) "# Java sources to be compiled: (listed in file $(JAVA_SOURCE_LIST))"; \
|
||||
$(CAT) $(JAVA_SOURCE_LIST); \
|
||||
$(ECHO) "# Running javac:"; \
|
||||
$(ECHO) $(JAVAC_CMD) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
|
||||
$(JAVAC_CMD) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
|
||||
$(ECHO) $(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
|
||||
$(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
|
||||
fi
|
||||
@$(java-vm-cleanup)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2009 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
|
||||
@ -128,9 +128,19 @@ ifeq ($(PLATFORM), windows)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CC_MAJORVER), 15)
|
||||
# This should be: CC_VER=15.00.21022.8 LINK_VER=9.00.21022.8
|
||||
REQUIRED_CC_VER = 15.00.21022.8
|
||||
REQUIRED_LINK_VER = 9.00.21022.8
|
||||
COMPILER_NAME=Windows SDK 6.1 Visual Studio 9
|
||||
COMPILER_VERSION=VS2008
|
||||
RC = $(MSSDK61)/bin/x64/rc
|
||||
REBASE = $(MSSDK61/bin/x64/rebase
|
||||
else
|
||||
# This will cause problems if ALT_COMPILER_PATH is defined to ""
|
||||
# which is a directive to use the PATH.
|
||||
REBASE = $(COMPILER_PATH)../REBASE
|
||||
endif
|
||||
ifndef COMPILER_PATH
|
||||
COMPILER_PATH := $(error COMPILER_PATH cannot be empty here)
|
||||
endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2009 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
|
||||
|
@ -104,6 +104,9 @@ ifeq ($(COMPILER_WARNINGS_FATAL), true)
|
||||
JAVACFLAGS += -Werror
|
||||
endif
|
||||
|
||||
NO_PROPRIETARY_API_WARNINGS = -XDignore.symbol.file=true
|
||||
JAVACFLAGS += $(NO_PROPRIETARY_API_WARNINGS)
|
||||
|
||||
# Add the source level (currently all source is 1.5, should this be 1.6?)
|
||||
LANGUAGE_VERSION = -source 1.5
|
||||
JAVACFLAGS += $(LANGUAGE_VERSION)
|
||||
@ -117,7 +120,7 @@ JAVACFLAGS += -classpath $(BOOTDIR)/lib/tools.jar
|
||||
JAVACFLAGS += $(OTHER_JAVACFLAGS)
|
||||
|
||||
# Needed for javah
|
||||
JAVAHFLAGS += -bootclasspath $(CLASSBINDIR)
|
||||
JAVAHFLAGS += -classpath $(CLASSBINDIR)
|
||||
|
||||
# Langtools
|
||||
ifdef LANGTOOLS_DIST
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2009 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
|
||||
|
@ -282,6 +282,19 @@ endif
|
||||
|
||||
# Compilers for 64bit are from SDK
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
|
||||
MSSDK61 :=$(call FullPath,$(xMSSDK61))
|
||||
xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
|
||||
_vs2008 :=$(call FullPath,$(xVS2008))
|
||||
ifneq ($(_vs2008),)
|
||||
ifeq ($(ARCH), ia64)
|
||||
_compiler_bin :=$(_vs2008)/VC/Bin/x86_ia64
|
||||
endif
|
||||
ifeq ($(ARCH), amd64)
|
||||
_compiler_bin :=$(_vs2008)/VC/Bin/$(ARCH)
|
||||
_redist_sdk :=$(MSSDK61)/VC/redist
|
||||
endif
|
||||
else
|
||||
ifneq ($(_ms_sdk),)
|
||||
ifeq ($(ARCH), ia64)
|
||||
_compiler_bin :=$(_ms_sdk)/Bin/Win64
|
||||
@ -292,6 +305,7 @@ ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Location on system where jdk installs might be
|
||||
ifneq ($(_program_files),)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2000-2009 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
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!echo "This is not a shell script"
|
||||
#############################################################################
|
||||
#
|
||||
# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2006-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1997-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 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
|
||||
@ -75,15 +75,14 @@ ORBUTIL.MC = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/ORBUtil.mc
|
||||
POA.MC = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/POA.mc
|
||||
UTIL.MC = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/Util.mc
|
||||
|
||||
MC_GENERATE_CLASS = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-class
|
||||
MC_GENERATE_LOG_RB = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-resource
|
||||
MC_GENERATE_CLASS = make-class
|
||||
MC_GENERATE_LOG_RB = make-resource
|
||||
|
||||
JSCHEME_LIB_DIRECTORY=$(SRC_DIR)/com/sun/tools/corba/se/logutil/lib
|
||||
JSCHEME_CLASSPATH=$(JSCHEME_LIB_DIRECTORY)/jscheme.jar$(CLASSPATH_SEPARATOR)$(JSCHEME_LIB_DIRECTORY)/jschemelogutil.jar
|
||||
JSCHEME_GENERATE_CLASS = $(BOOT_JAVA_CMD) \
|
||||
-cp "$(JSCHEME_CLASSPATH)" jscheme.REPL $(MC_GENERATE_CLASS)
|
||||
JSCHEME_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) \
|
||||
-cp "$(JSCHEME_CLASSPATH)" jscheme.REPL $(MC_GENERATE_LOG_RB)
|
||||
MC_CLASSPATH=$(BUILDTOOLJARDIR)/MC.jar
|
||||
MCJ_GENERATE_CLASS = $(BOOT_JAVA_CMD) \
|
||||
-cp "$(MC_CLASSPATH)" com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_CLASS)
|
||||
MCJ_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) \
|
||||
-cp "$(MC_CLASSPATH)" com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_LOG_RB)
|
||||
|
||||
|
||||
#
|
||||
@ -104,28 +103,28 @@ $(LOG_GENDIRECTORY):
|
||||
$(MKDIR) -p $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/ActivationSystemException.java : $(ACTIVATION.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/IORSystemException.java : $(IOR.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(IOR.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(IOR.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/InterceptorsSystemException.java : $(INTERCEPTORS.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/NamingSystemException.java : $(NAMING.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(NAMING.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(NAMING.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/OMGSystemException.java : $(OMG.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(OMG.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(OMG.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/ORBUtilSystemException.java : $(ORBUTIL.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/POASystemException.java : $(POA.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(POA.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(POA.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/UtilSystemException.java : $(UTIL.MC)
|
||||
$(JSCHEME_GENERATE_CLASS) $(UTIL.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_CLASS) $(UTIL.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
logresource.generate: $(LOG_GENDIRECTORY)/LogStrings.properties
|
||||
|
||||
@ -142,28 +141,28 @@ $(LOG_GENDIRECTORY)/LogStrings.properties: \
|
||||
$(CAT) $(LOG_GENDIRECTORY)/*.resource > $(LOG_GENDIRECTORY)/LogStrings.properties
|
||||
|
||||
$(LOG_GENDIRECTORY)/ActivationSystemException.resource : $(ACTIVATION.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/IORSystemException.resource : $(IOR.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(IOR.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(IOR.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/InterceptorsSystemException.resource : $(INTERCEPTORS.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/NamingSystemException.resource : $(NAMING.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(NAMING.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(NAMING.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/OMGSystemException.resource : $(OMG.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(OMG.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(OMG.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/ORBUtilSystemException.resource : $(ORBUTIL.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/POASystemException.resource : $(POA.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(POA.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(POA.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
$(LOG_GENDIRECTORY)/UtilSystemException.resource : $(UTIL.MC)
|
||||
$(JSCHEME_GENERATE_LOG_RB) $(UTIL.MC) $(LOG_GENDIRECTORY)
|
||||
$(MCJ_GENERATE_LOG_RB) $(UTIL.MC) $(LOG_GENDIRECTORY)
|
||||
|
||||
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1998-2009 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
|
||||
@ -33,6 +33,7 @@ include $(BUILDDIR)/common/Defs.gmk
|
||||
SUBDIRS = \
|
||||
strip_properties \
|
||||
idlj \
|
||||
logutil \
|
||||
|
||||
all build clean clobber::
|
||||
$(SUBDIRS-loop)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 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
|
||||
@ -24,24 +24,20 @@
|
||||
#
|
||||
|
||||
#
|
||||
# Compiler settings for all platforms and the default compiler for each.
|
||||
# Makefile for building the idlj tool
|
||||
#
|
||||
|
||||
# Windows uses Microsoft compilers by default
|
||||
ifeq ($(PLATFORM), windows)
|
||||
override CC_VERSION = msvc
|
||||
endif
|
||||
BUILDDIR = ../..
|
||||
PACKAGE = com.sun.tools.corba.se.logutil
|
||||
PRODUCT = tools
|
||||
PROGRAM = MC
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
|
||||
# Solaris uses Sun Studio compilers by default
|
||||
ifeq ($(PLATFORM), solaris)
|
||||
override CC_VERSION = sun
|
||||
endif
|
||||
BUILDTOOL_SOURCE_ROOT = $(SHARE_SRC)/classes
|
||||
BUILDTOOL_MAIN = $(PKGDIR)/MC.java
|
||||
|
||||
# Linux uses GNU compilers by default
|
||||
ifeq ($(PLATFORM), linux)
|
||||
override CC_VERSION = gcc
|
||||
endif
|
||||
|
||||
# Get the compiler specific settings
|
||||
include $(JDK_MAKE_SHARED_DIR)/Compiler-$(CC_VERSION).gmk
|
||||
#
|
||||
# Build tool jar rules.
|
||||
#
|
||||
include $(BUILDDIR)/common/BuildToolJar.gmk
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009 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
|
||||
@ -30,7 +30,6 @@ import java.io.Writer ;
|
||||
import java.io.OutputStream ;
|
||||
import java.io.BufferedWriter ;
|
||||
import java.io.OutputStreamWriter ;
|
||||
import jsint.Pair ;
|
||||
import java.util.StringTokenizer ;
|
||||
|
||||
public class IndentingPrintWriter extends PrintWriter {
|
||||
@ -38,22 +37,20 @@ public class IndentingPrintWriter extends PrintWriter {
|
||||
private int indentWidth = 4 ;
|
||||
private String indentString = "" ;
|
||||
|
||||
public void printMsg( String msg, Pair data )
|
||||
public void printMsg( String msg, Object... data )
|
||||
{
|
||||
// System.out.println( "printMsg called with msg=" + msg + " data=" + data ) ;
|
||||
StringTokenizer st = new StringTokenizer( msg, "@", true ) ;
|
||||
StringBuffer result = new StringBuffer() ;
|
||||
Object head = data.first ;
|
||||
Pair tail = (Pair)data.rest ;
|
||||
String token = null ;
|
||||
int pos = 0;
|
||||
|
||||
while (st.hasMoreTokens()) {
|
||||
token = st.nextToken() ;
|
||||
if (token.equals("@")) {
|
||||
if (head != null) {
|
||||
result.append( head ) ;
|
||||
head = tail.first ;
|
||||
tail = (Pair)tail.rest ;
|
||||
if (pos < data.length) {
|
||||
result.append( data[pos] );
|
||||
++pos;
|
||||
} else {
|
||||
throw new Error( "List too short for message" ) ;
|
||||
}
|
||||
|
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 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. 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.corba.se.logutil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Input {
|
||||
|
||||
/**
|
||||
* The name of the package this class will inhabit.
|
||||
*/
|
||||
private String packageName;
|
||||
|
||||
/**
|
||||
* The name of the generated class.
|
||||
*/
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* The name of the group of exceptions handled by the class.
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* The group of exceptions.
|
||||
*/
|
||||
private Queue<InputException> exceptions;
|
||||
|
||||
/**
|
||||
* Represents the current state of parsing the input.
|
||||
*/
|
||||
private enum State
|
||||
{
|
||||
OUTER,
|
||||
IN_CLASS,
|
||||
IN_EXCEPTION_LIST
|
||||
};
|
||||
|
||||
/**
|
||||
* Regular expression to match each code line.
|
||||
*/
|
||||
private static final Pattern EXCEPTION_INFO_REGEX =
|
||||
Pattern.compile("(\\w+)\\s*(\\d+)\\s*(\\w+)");
|
||||
|
||||
/**
|
||||
* Parses the specified file to create a new {@link Input}
|
||||
* object.
|
||||
*
|
||||
* @param filename the file to parse.
|
||||
* @throws FileNotFoundException if the file can't be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public Input(final String filename)
|
||||
throws FileNotFoundException, IOException {
|
||||
BufferedReader r =
|
||||
new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
|
||||
State state = State.OUTER;
|
||||
InputException current = null;
|
||||
exceptions = new LinkedList<InputException>();
|
||||
String line;
|
||||
while ((line = r.readLine()) != null) {
|
||||
// Skip ; comments
|
||||
if (line.startsWith(";"))
|
||||
continue;
|
||||
|
||||
int index = line.indexOf("(");
|
||||
if (index == -1)
|
||||
continue;
|
||||
|
||||
switch (state) {
|
||||
case OUTER:
|
||||
state = State.IN_CLASS;
|
||||
String[] classInfo = line.substring(index).split(" ");
|
||||
packageName = classInfo[0].substring(2, classInfo[0].length() - 1);
|
||||
className = classInfo[1].substring(1, classInfo[1].length() - 1);
|
||||
groupName = classInfo[2];
|
||||
break;
|
||||
case IN_CLASS:
|
||||
state = State.IN_EXCEPTION_LIST;
|
||||
break;
|
||||
case IN_EXCEPTION_LIST:
|
||||
boolean inQuote = false;
|
||||
boolean inCode = false;
|
||||
boolean end = false;
|
||||
int start = index + 1;
|
||||
Queue<String> lines = new LinkedList<String>();
|
||||
for (int a = start; a < line.length(); ++a) {
|
||||
if (line.charAt(a) == '(' && !inCode && !inQuote) {
|
||||
if (current == null)
|
||||
current =
|
||||
new InputException(line.substring(start, a).trim());
|
||||
start = a + 1;
|
||||
inCode = true;
|
||||
}
|
||||
if (line.charAt(a) == '"')
|
||||
inQuote = !inQuote;
|
||||
if (line.charAt(a) == ')' && !inQuote) {
|
||||
if (inCode) {
|
||||
lines.offer(line.substring(start, a));
|
||||
inCode = false;
|
||||
} else
|
||||
end = true;
|
||||
}
|
||||
if (!end && a == line.length() - 1)
|
||||
line += r.readLine();
|
||||
}
|
||||
for (String l : lines) {
|
||||
int stringStart = l.indexOf("\"") + 1;
|
||||
int stringEnd = l.indexOf("\"", stringStart);
|
||||
Matcher matcher = EXCEPTION_INFO_REGEX.matcher(l.substring(0, stringStart));
|
||||
if (matcher.find())
|
||||
current.add(new InputCode(matcher.group(1),
|
||||
Integer.parseInt(matcher.group(2)),
|
||||
matcher.group(3),
|
||||
l.substring(stringStart, stringEnd)));
|
||||
}
|
||||
exceptions.offer(current);
|
||||
current = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this group of exceptions.
|
||||
*
|
||||
* @return the name of this group of exceptions.
|
||||
*/
|
||||
public String getGroupName()
|
||||
{
|
||||
return groupName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the package this class will go in.
|
||||
*
|
||||
* @return the name of the package.
|
||||
*/
|
||||
public String getPackageName()
|
||||
{
|
||||
return packageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the generated class.
|
||||
*
|
||||
* @return the name of the class.
|
||||
*/
|
||||
public String getClassName()
|
||||
{
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exceptions contained in this class.
|
||||
*
|
||||
* @return the exceptions.
|
||||
*/
|
||||
public Queue<InputException> getExceptions() {
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual representation of this input.
|
||||
*
|
||||
* @return a textual representation.
|
||||
*/
|
||||
public String toString() {
|
||||
return getClass().getName() +
|
||||
"[packageName=" + packageName +
|
||||
",className=" + className +
|
||||
",groupName=" + groupName +
|
||||
",exceptions=" + exceptions +
|
||||
"]";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 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. 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.
|
||||
*/
|
||||
package com.sun.tools.corba.se.logutil;
|
||||
|
||||
public class InputCode {
|
||||
|
||||
/**
|
||||
* The name of this code.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The code.
|
||||
*/
|
||||
private final int code;
|
||||
|
||||
/**
|
||||
* The log level for this code.
|
||||
*/
|
||||
private final String logLevel;
|
||||
|
||||
/**
|
||||
* The error message for this code.
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* Creates a new error code with the specified name, code,
|
||||
* log level and error message.
|
||||
*
|
||||
* @param name the name of the new code.
|
||||
* @param code the code itself.
|
||||
* @param logLevel the level of severity of this error.
|
||||
* @param message the error message for this code.
|
||||
*/
|
||||
public InputCode(final String name, final int code,
|
||||
final String logLevel, final String message) {
|
||||
this.name = name;
|
||||
this.code = code;
|
||||
this.logLevel = logLevel;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this code.
|
||||
*
|
||||
* @return the name of the code.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code.
|
||||
*
|
||||
* @return the code.
|
||||
*/
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the severity of this code.
|
||||
*
|
||||
* @return the log level severity of the code.
|
||||
*/
|
||||
public String getLogLevel() {
|
||||
return logLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message for this code.
|
||||
*
|
||||
* @return the error message for this code.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual representation of this code.
|
||||
*
|
||||
* @return a textual representation.
|
||||
*/
|
||||
public String toString() {
|
||||
return getClass().getName() +
|
||||
"[name=" + name +
|
||||
",code=" + code +
|
||||
",logLevel=" + logLevel +
|
||||
",message=" + message +
|
||||
"]";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 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. 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.
|
||||
*/
|
||||
package com.sun.tools.corba.se.logutil;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class InputException {
|
||||
|
||||
/**
|
||||
* The name of this exception.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The codes associated with this exception.
|
||||
*/
|
||||
private final Queue<InputCode> codes;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link InputException} with the
|
||||
* specified name.
|
||||
*
|
||||
* @param name the name of the new exception;
|
||||
*/
|
||||
public InputException(final String name) {
|
||||
this.name = name;
|
||||
codes = new LinkedList<InputCode>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new code to this exception.
|
||||
*
|
||||
* @param c the code to add.
|
||||
*/
|
||||
public void add(InputCode c)
|
||||
{
|
||||
codes.offer(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this exception.
|
||||
*
|
||||
* @return the exception's name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codes associated with this exception.
|
||||
*
|
||||
* @return the exception's codes.
|
||||
*/
|
||||
public Queue<InputCode> getCodes() {
|
||||
return codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual representation of this exception.
|
||||
*
|
||||
* @return a textual representation.
|
||||
*/
|
||||
public String toString() {
|
||||
return getClass().getName()
|
||||
+ "[name=" + name
|
||||
+ ",codes=" + codes
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
559
corba/src/share/classes/com/sun/tools/corba/se/logutil/MC.java
Normal file
559
corba/src/share/classes/com/sun/tools/corba/se/logutil/MC.java
Normal file
@ -0,0 +1,559 @@
|
||||
/*
|
||||
* Copyright 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. 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.
|
||||
*/
|
||||
package com.sun.tools.corba.se.logutil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Formatter;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
public class MC {
|
||||
|
||||
private static final String VERSION = "1.0";
|
||||
|
||||
private static final List<String> SUN_EXCEPTION_GROUPS = Arrays.asList(new String[]
|
||||
{ "SUNBASE", "ORBUTIL", "ACTIVATION", "NAMING", "INTERCEPTORS", "POA", "IOR", "UTIL" });
|
||||
|
||||
private static final List<String> EXCEPTIONS = Arrays.asList(new String[]
|
||||
{ "UNKNOWN", "BAD_PARAM", "NO_MEMORY", "IMP_LIMIT", "COMM_FAILURE", "INV_OBJREF", "NO_PERMISSION",
|
||||
"INTERNAL", "MARSHAL", "INITIALIZE", "NO_IMPLEMENT", "BAD_TYPECODE", "BAD_OPERATION", "NO_RESOURCES",
|
||||
"NO_RESPONSE", "PERSIST_STORE", "BAD_INV_ORDER", "TRANSIENT", "FREE_MEM", "INV_IDENT", "INV_FLAG",
|
||||
"INTF_REPOS", "BAD_CONTEXT", "OBJ_ADAPTER", "DATA_CONVERSION", "OBJECT_NOT_EXIST", "TRANSACTION_REQUIRED",
|
||||
"TRANSACTION_ROLLEDBACK", "INVALID_TRANSACTION", "INV_POLICY", "CODESET_INCOMPATIBLE", "REBIND",
|
||||
"TIMEOUT", "TRANSACTION_UNAVAILABLE", "BAD_QOS", "INVALID_ACTIVITY", "ACTIVITY_COMPLETED",
|
||||
"ACTIVITY_REQUIRED" });
|
||||
|
||||
/**
|
||||
* Read the minor codes from the input file and
|
||||
* write out a resource file.
|
||||
*
|
||||
* @param inFile the file to read the codes from.
|
||||
* @param outDir the directory to write the resource file to.
|
||||
* @throws FileNotFoundException if the input file can not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void makeResource(String inFile, String outDir)
|
||||
throws FileNotFoundException, IOException {
|
||||
writeResource(outDir, new Input(inFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Java source file using the specified Scheme input file,
|
||||
* and writing the result to the given output directory.
|
||||
*
|
||||
* @param inFile the file to read the data from.
|
||||
* @param outDir the directory to write the Java class to.
|
||||
* @throws FileNotFoundException if the input file can not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void makeClass(String inFile, String outDir)
|
||||
throws FileNotFoundException, IOException {
|
||||
writeClass(inFile, outDir, new Input(inFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a Java source file using the data from the given
|
||||
* {@link Input} object. The result is written to {@code outDir}.
|
||||
* The name of the input file is just used in the header of the
|
||||
* resulting source file.
|
||||
*
|
||||
* @param inFile the name of the file the data was read from.
|
||||
* @param outDir the directory to write the Java class to.
|
||||
* @param input the parsed input data.
|
||||
* @throws FileNotFoundException if the output file can't be written.
|
||||
*/
|
||||
private void writeClass(String inFile, String outDir, Input input)
|
||||
throws FileNotFoundException {
|
||||
String packageName = input.getPackageName();
|
||||
String className = input.getClassName();
|
||||
String groupName = input.getGroupName();
|
||||
Queue<InputException> exceptions = input.getExceptions();
|
||||
FileOutputStream file = new FileOutputStream(outDir + File.separator + className + ".java");
|
||||
IndentingPrintWriter pw = new IndentingPrintWriter(file);
|
||||
|
||||
writeClassHeader(inFile, groupName, pw);
|
||||
pw.printMsg("package @ ;", packageName);
|
||||
pw.println();
|
||||
pw.println("import java.util.logging.Logger ;");
|
||||
pw.println("import java.util.logging.Level ;");
|
||||
pw.println();
|
||||
pw.println("import org.omg.CORBA.OMGVMCID ;");
|
||||
pw.println( "import com.sun.corba.se.impl.util.SUNVMCID ;");
|
||||
pw.println( "import org.omg.CORBA.CompletionStatus ;");
|
||||
pw.println( "import org.omg.CORBA.SystemException ;");
|
||||
pw.println();
|
||||
pw.println( "import com.sun.corba.se.spi.orb.ORB ;");
|
||||
pw.println();
|
||||
pw.println( "import com.sun.corba.se.spi.logging.LogWrapperFactory;");
|
||||
pw.println();
|
||||
pw.println( "import com.sun.corba.se.spi.logging.LogWrapperBase;");
|
||||
pw.println();
|
||||
writeImports(exceptions, pw);
|
||||
pw.println();
|
||||
pw.indent();
|
||||
pw.printMsg("public class @ extends LogWrapperBase {", className);
|
||||
pw.println();
|
||||
pw.printMsg("public @( Logger logger )", className);
|
||||
pw.indent();
|
||||
pw.println( "{");
|
||||
pw.undent();
|
||||
pw.println( "super( logger ) ;");
|
||||
pw.println( "}");
|
||||
pw.println();
|
||||
pw.flush();
|
||||
writeFactoryMethod(className, groupName, pw);
|
||||
writeExceptions(groupName, exceptions, className, pw);
|
||||
pw.undent();
|
||||
pw.println( );
|
||||
pw.println( "}");
|
||||
pw.flush();
|
||||
pw.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the header of a Java source file.
|
||||
*
|
||||
* @param inFile the input file the file was generated from.
|
||||
* @param groupName the group of exceptions the Java source file is for.
|
||||
* @param pw the print writer used to write the output.
|
||||
*/
|
||||
private void writeClassHeader(String inFile, String groupName,
|
||||
IndentingPrintWriter pw) {
|
||||
if (groupName.equals("OMG"))
|
||||
pw.println("// Log wrapper class for standard exceptions");
|
||||
else
|
||||
pw.printMsg("// Log wrapper class for Sun private system exceptions in group @",
|
||||
groupName);
|
||||
pw.println("//");
|
||||
pw.printMsg("// Generated by MC.java version @, DO NOT EDIT BY HAND!", VERSION);
|
||||
pw.printMsg("// Generated from input file @ on @", inFile, new Date());
|
||||
pw.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the import list for the exceptions.
|
||||
*
|
||||
* @param groups the exceptions that were parsed.
|
||||
* @param pw the {@link IndentingPrintWriter} for writing to the file.
|
||||
*/
|
||||
private void writeImports(Queue<InputException> exceptions,
|
||||
IndentingPrintWriter pw) {
|
||||
if (exceptions == null)
|
||||
return;
|
||||
for (InputException e : exceptions)
|
||||
pw.println("import org.omg.CORBA." + e.getName() + " ;");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the factory method for this group of exceptions.
|
||||
*
|
||||
* @param className the name of the generated class.
|
||||
* @param groupName the name of this group of exceptions.
|
||||
* @param pw the {@link IndentingPrintWriter} for writing to the file.
|
||||
*/
|
||||
private void writeFactoryMethod(String className, String groupName,
|
||||
IndentingPrintWriter pw) {
|
||||
pw.indent();
|
||||
pw.println( "private static LogWrapperFactory factory = new LogWrapperFactory() {");
|
||||
pw.println( "public LogWrapperBase create( Logger logger )" );
|
||||
pw.indent();
|
||||
pw.println( "{");
|
||||
pw.undent();
|
||||
pw.printMsg("return new @( logger ) ;", className);
|
||||
pw.undent();
|
||||
pw.println( "}" );
|
||||
pw.println( "} ;" );
|
||||
pw.println();
|
||||
pw.printMsg("public static @ get( ORB orb, String logDomain )", className);
|
||||
pw.indent();
|
||||
pw.println( "{");
|
||||
pw.indent();
|
||||
pw.printMsg( "@ wrapper = ", className);
|
||||
pw.indent();
|
||||
pw.printMsg( "(@) orb.getLogWrapper( logDomain, ", className);
|
||||
pw.undent();
|
||||
pw.undent();
|
||||
pw.printMsg( "\"@\", factory ) ;", groupName);
|
||||
pw.undent();
|
||||
pw.println( "return wrapper ;" );
|
||||
pw.println( "} " );
|
||||
pw.println();
|
||||
pw.printMsg( "public static @ get( String logDomain )", className);
|
||||
pw.indent();
|
||||
pw.println( "{");
|
||||
pw.indent();
|
||||
pw.printMsg( "@ wrapper = ", className);
|
||||
pw.indent();
|
||||
pw.printMsg( "(@) ORB.staticGetLogWrapper( logDomain, ", className);
|
||||
pw.undent();
|
||||
pw.undent();
|
||||
pw.printMsg( "\"@\", factory ) ;", groupName);
|
||||
pw.undent();
|
||||
pw.println( "return wrapper ;" );
|
||||
pw.println( "} " );
|
||||
pw.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the exceptions themselves.
|
||||
*
|
||||
* @param groupName the name of this group of exceptions.
|
||||
* @param exceptions the exceptions to write out.
|
||||
* @param className the name of the generated class.
|
||||
* @param pw the {@link IndentingPrintWriter} for writing to the file.
|
||||
*/
|
||||
private void writeExceptions(String groupName, Queue<InputException> exceptions,
|
||||
String className, IndentingPrintWriter pw) {
|
||||
for (InputException e : exceptions) {
|
||||
pw.println("///////////////////////////////////////////////////////////");
|
||||
pw.printMsg("// @", e.getName());
|
||||
pw.println("///////////////////////////////////////////////////////////");
|
||||
pw.println();
|
||||
for (InputCode c : e.getCodes())
|
||||
writeMethods(groupName, e.getName(), c.getName(), c.getCode(),
|
||||
c.getLogLevel(), className, StringUtil.countArgs(c.getMessage()), pw);
|
||||
pw.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the methods for a particular error.
|
||||
*
|
||||
* @param groupName the name of this group of exceptions.
|
||||
* @param exceptionName the name of this particular exception.
|
||||
* @param errorName the name of this particular error.
|
||||
* @param code the minor code for this particular error.
|
||||
* @param ident the name of the error in mixed-case identifier form.
|
||||
* @param level the level at which to place log messages.
|
||||
* @param className the name of the class for this group of exceptions.
|
||||
* @param numParams the number of parameters the detail message takes.
|
||||
* @param pw the print writer for writing to the file.
|
||||
*/
|
||||
private void writeMethods(String groupName, String exceptionName, String errorName,
|
||||
int code, String level, String className, int numParams,
|
||||
IndentingPrintWriter pw) {
|
||||
String ident = StringUtil.toMixedCase(errorName);
|
||||
pw.printMsg("public static final int @ = @ ;", errorName, getBase(groupName, code));
|
||||
pw.println();
|
||||
pw.flush();
|
||||
writeMethodStatusCause(groupName, exceptionName, errorName, ident, level,
|
||||
numParams, className, pw);
|
||||
pw.println();
|
||||
pw.flush();
|
||||
writeMethodStatus(exceptionName, ident, numParams, pw);
|
||||
pw.println();
|
||||
pw.flush();
|
||||
writeMethodCause(exceptionName, ident, numParams, pw);
|
||||
pw.println();
|
||||
pw.flush();
|
||||
writeMethodNoArgs(exceptionName, ident, numParams, pw);
|
||||
pw.println();
|
||||
pw.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a method for an error that takes a
|
||||
* {@link org.omg.CORBA.CompletionStatus} and a cause.
|
||||
*
|
||||
* @param groupName the name of this group of exceptions.
|
||||
* @param exceptionName the name of this particular exception.
|
||||
* @param errorName the name of this particular error.
|
||||
* @param ident the name of the error in mixed-case identifier form.
|
||||
* @param logLevel the level at which to place log messages.
|
||||
* @param numParams the number of parameters the detail message takes.
|
||||
* @param className the name of the class for this group of exceptions.
|
||||
* @param pw the print writer for writing to the file.
|
||||
*/
|
||||
private void writeMethodStatusCause(String groupName, String exceptionName,
|
||||
String errorName, String ident,
|
||||
String logLevel, int numParams,
|
||||
String className, IndentingPrintWriter pw) {
|
||||
pw.indent();
|
||||
pw.printMsg( "public @ @( CompletionStatus cs, Throwable t@) {", exceptionName,
|
||||
ident, makeDeclArgs(true, numParams));
|
||||
pw.printMsg( "@ exc = new @( @, cs ) ;", exceptionName, exceptionName, errorName);
|
||||
pw.indent();
|
||||
pw.println( "if (t != null)" );
|
||||
pw.undent();
|
||||
pw.println( "exc.initCause( t ) ;" );
|
||||
pw.println();
|
||||
pw.indent();
|
||||
pw.printMsg( "if (logger.isLoggable( Level.@ )) {", logLevel);
|
||||
if (numParams > 0) {
|
||||
pw.printMsg( "Object[] parameters = new Object[@] ;", numParams);
|
||||
for (int a = 0; a < numParams; ++a)
|
||||
pw.printMsg("parameters[@] = arg@ ;", a, a);
|
||||
} else
|
||||
pw.println( "Object[] parameters = null ;");
|
||||
pw.indent();
|
||||
pw.printMsg( "doLog( Level.@, \"@.@\",", logLevel, groupName, ident);
|
||||
pw.undent();
|
||||
pw.undent();
|
||||
pw.printMsg( "parameters, @.class, exc ) ;", className);
|
||||
pw.println( "}");
|
||||
pw.println();
|
||||
|
||||
pw.undent();
|
||||
pw.println( "return exc ;");
|
||||
pw.println( "}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a method for an error that takes a
|
||||
* {@link org.omg.CORBA.CompletionStatus}.
|
||||
*
|
||||
* @param exceptionName the name of this particular exception.
|
||||
* @param ident the name of the error in mixed-case identifier form.
|
||||
* @param numParams the number of parameters the detail message takes.
|
||||
* @param pw the print writer for writing to the file.
|
||||
*/
|
||||
private void writeMethodStatus(String exceptionName, String ident,
|
||||
int numParams, IndentingPrintWriter pw) {
|
||||
pw.indent();
|
||||
pw.printMsg("public @ @( CompletionStatus cs@) {", exceptionName,
|
||||
ident, makeDeclArgs(true, numParams));
|
||||
pw.undent();
|
||||
pw.printMsg("return @( cs, null@ ) ;", ident, makeCallArgs(true, numParams));
|
||||
pw.println("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a method for an error that takes a cause.
|
||||
*
|
||||
* @param exceptionName the name of this particular exception.
|
||||
* @param ident the name of the error in mixed-case identifier form.
|
||||
* @param numParams the number of parameters the detail message takes.
|
||||
* @param pw the print writer for writing to the file.
|
||||
*/
|
||||
private void writeMethodCause(String exceptionName, String ident,
|
||||
int numParams, IndentingPrintWriter pw) {
|
||||
pw.indent();
|
||||
pw.printMsg("public @ @( Throwable t@) {", exceptionName, ident,
|
||||
makeDeclArgs(true, numParams));
|
||||
pw.undent();
|
||||
pw.printMsg("return @( CompletionStatus.COMPLETED_NO, t@ ) ;", ident,
|
||||
makeCallArgs(true, numParams));
|
||||
pw.println("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a method for an error that takes no arguments.
|
||||
*
|
||||
* @param exceptionName the name of this particular exception.
|
||||
* @param ident the name of the error in mixed-case identifier form.
|
||||
* @param numParams the number of parameters the detail message takes.
|
||||
* @param pw the print writer for writing to the file.
|
||||
*/
|
||||
private void writeMethodNoArgs(String exceptionName, String ident,
|
||||
int numParams, IndentingPrintWriter pw) {
|
||||
|
||||
pw.indent();
|
||||
pw.printMsg("public @ @( @) {", exceptionName, ident,
|
||||
makeDeclArgs(false, numParams));
|
||||
pw.undent();
|
||||
pw.printMsg("return @( CompletionStatus.COMPLETED_NO, null@ ) ;",
|
||||
ident, makeCallArgs(true, numParams));
|
||||
pw.println("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of comma-separated arguments with type declarations.
|
||||
*
|
||||
* @param leadingComma true if the list should start with a comma.
|
||||
* @param numArgs the number of arguments to generate.
|
||||
* @return the generated string.
|
||||
*/
|
||||
private String makeDeclArgs(boolean leadingComma, int numArgs) {
|
||||
return makeArgString("Object arg", leadingComma, numArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of comma-separated arguments without type declarations.
|
||||
*
|
||||
* @param leadingComma true if the list should start with a comma.
|
||||
* @param numArgs the number of arguments to generate.
|
||||
* @return the generated string.
|
||||
*/
|
||||
private String makeCallArgs(boolean leadingComma, int numArgs) {
|
||||
return makeArgString("arg", leadingComma, numArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of comma-separated arguments.
|
||||
*
|
||||
* @param prefixString the string with which to prefix each argument.
|
||||
* @param leadingComma true if the list should start with a comma.
|
||||
* @param numArgs the number of arguments to generate.
|
||||
* @return the generated string.
|
||||
*/
|
||||
private String makeArgString(String prefixString, boolean leadingComma,
|
||||
int numArgs) {
|
||||
if (numArgs == 0)
|
||||
return " ";
|
||||
if (numArgs == 1) {
|
||||
if (leadingComma)
|
||||
return ", " + prefixString + (numArgs - 1);
|
||||
else
|
||||
return " " + prefixString + (numArgs - 1);
|
||||
}
|
||||
return makeArgString(prefixString, leadingComma, numArgs - 1) +
|
||||
", " + prefixString + (numArgs - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link String} containing the calculation of the
|
||||
* error code.
|
||||
*
|
||||
* @param groupName the group of exception to which the code belongs.
|
||||
* @param code the minor code number representing the exception within the group.
|
||||
* @return the unique error code.
|
||||
*/
|
||||
private String getBase(String groupName, int code) {
|
||||
if (groupName.equals("OMG"))
|
||||
return "OMGVMCID.value + " + code;
|
||||
else
|
||||
return "SUNVMCID.value + " + (code + getSunBaseNumber(groupName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base number for Sun-specific exceptions.
|
||||
*
|
||||
* @return the base number.
|
||||
*/
|
||||
private int getSunBaseNumber(String groupName) {
|
||||
return 200 * SUN_EXCEPTION_GROUPS.indexOf(groupName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a resource file using the data from the given
|
||||
* {@link Input} object. The result is written to {@code outDir}.
|
||||
*
|
||||
* @param outDir the directory to write the Java class to.
|
||||
* @param input the parsed input data.
|
||||
* @throws FileNotFoundException if the output file can't be written.
|
||||
*/
|
||||
private void writeResource(String outDir, Input input)
|
||||
throws FileNotFoundException {
|
||||
FileOutputStream file = new FileOutputStream(outDir + File.separator +
|
||||
input.getClassName() + ".resource");
|
||||
IndentingPrintWriter pw = new IndentingPrintWriter(file);
|
||||
String groupName = input.getGroupName();
|
||||
for (InputException e : input.getExceptions()) {
|
||||
String exName = e.getName();
|
||||
for (InputCode c : e.getCodes()) {
|
||||
String ident = StringUtil.toMixedCase(c.getName());
|
||||
pw.printMsg("@.@=\"@: (@) @\"", groupName, ident,
|
||||
getMessageID(groupName, exName, c.getCode()), exName, c.getMessage());
|
||||
}
|
||||
pw.flush();
|
||||
}
|
||||
pw.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message ID corresponding to the given group name,
|
||||
* exception name and error code.
|
||||
*
|
||||
* @param groupName the name of the group of exceptions.
|
||||
* @param exception the name of the particular exception.
|
||||
* @param code an error code from the given exception.
|
||||
* @return the message ID.
|
||||
*/
|
||||
private String getMessageID(String groupName, String exceptionName, int code) {
|
||||
if (groupName.equals("OMG"))
|
||||
return getStandardMessageID(exceptionName, code);
|
||||
else
|
||||
return getSunMessageID(groupName, exceptionName, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard (OMG) message ID corresponding to the given
|
||||
* exception name and error code.
|
||||
*
|
||||
* @param exceptionName the name of the particular exception.
|
||||
* @param code an error code from the given exception.
|
||||
* @return the message ID.
|
||||
*/
|
||||
private String getStandardMessageID(String exceptionName, int code) {
|
||||
return new Formatter().format("IOP%s0%04d", getExceptionID(exceptionName),
|
||||
code).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Sun message ID corresponding to the given group name,
|
||||
* exception name and error code.
|
||||
*
|
||||
* @param groupName the name of the group of exceptions.
|
||||
* @param exceptionName the name of the particular exception.
|
||||
* @param code an error code from the given exception.
|
||||
* @return the message ID.
|
||||
*/
|
||||
private String getSunMessageID(String groupName, String exceptionName, int code) {
|
||||
return new Formatter().format("IOP%s1%04d", getExceptionID(exceptionName),
|
||||
getSunBaseNumber(groupName) + code).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception ID corresponding to the given exception name.
|
||||
*
|
||||
* @param exceptionName the name of the particular exception.
|
||||
* @return the message ID.
|
||||
*/
|
||||
private String getExceptionID(String exceptionName) {
|
||||
return new Formatter().format("%03d", EXCEPTIONS.indexOf(exceptionName)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point for running the generator from the command
|
||||
* line. Users can specify either "make-class" or "make-resource"
|
||||
* as the first argument to generate the specified type of file.
|
||||
*
|
||||
* @param args the command-line arguments.
|
||||
* @throws FileNotFoundException if the input file can not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
throws FileNotFoundException, IOException
|
||||
{
|
||||
if (args.length < 3)
|
||||
{
|
||||
System.err.println("(make-class|make-resource) <input file> <output dir>");
|
||||
System.exit(-1);
|
||||
}
|
||||
if (args[0].equals("make-class"))
|
||||
new MC().makeClass(args[1], args[2]);
|
||||
else if (args[0].equals("make-resource"))
|
||||
new MC().makeResource(args[1], args[2]);
|
||||
else
|
||||
System.err.println("Invalid command: " + args[0]);
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
#! /bin/sh
|
||||
java -cp lib/jscheme.jar:lib/util.jar jscheme.REPL mc.scm -main main $@
|
@ -1,662 +0,0 @@
|
||||
; Scheme program to produce CORBA standard exceptions class
|
||||
; requires Jscheme Java extensions
|
||||
; Makes use of some custom Java classes also
|
||||
|
||||
(import "com.sun.tools.corba.se.logutil.IndentingPrintWriter" )
|
||||
(import "com.sun.tools.corba.se.logutil.StringUtil" )
|
||||
(import "java.io.FileOutputStream")
|
||||
|
||||
(define version-string "1.3")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Utility functions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; reload this file (convenience definition)
|
||||
(define (reload) (load "mc.scm"))
|
||||
|
||||
; Simple little function to report an error
|
||||
(define (error msg)
|
||||
(throw (Error. msg)))
|
||||
|
||||
; some debug support
|
||||
(define debug #f)
|
||||
|
||||
(define (dprint msg)
|
||||
(if debug
|
||||
(.println System.out$ msg)))
|
||||
|
||||
; Replace dprint with noprint to avoid seeing messages when debug is #t
|
||||
(define (noprint msg) ())
|
||||
|
||||
; Helper function present so that a scheme method taking strings as args
|
||||
; can be easily run from a command line.
|
||||
; arg: vector containing argument strings. Element 0 is the function name
|
||||
; to execute
|
||||
(define (main arg)
|
||||
(let*
|
||||
(
|
||||
(arg-list (vector->list arg))
|
||||
(function-symbol (string->symbol (car arg-list)))
|
||||
(args (cdr arg-list)))
|
||||
(apply (eval function-symbol) args)))
|
||||
|
||||
; Returns the position of key in lst, numbering from 0. key is matched using eqv?
|
||||
(define (get-list-position key lst)
|
||||
(letrec
|
||||
(
|
||||
(helper (lambda (k l accum)
|
||||
(cond
|
||||
((null? l) (error (string-append "Could not find " k)))
|
||||
((eqv? k (car l)) accum)
|
||||
(else (helper k (cdr l) (+ accum 1))) ))))
|
||||
(begin
|
||||
(noprint (string-append "get-list-position called with key " key " lst " lst ))
|
||||
(helper key lst 0))))
|
||||
|
||||
; Return a string representing number in decimal padded to length with leading 0s.
|
||||
(define (pad-number-string number length)
|
||||
(let*
|
||||
(
|
||||
(number-string (number->string number))
|
||||
(pad-length (- length (string-length number-string)))
|
||||
)
|
||||
(string-append (make-string pad-length #\0) number-string)))
|
||||
|
||||
; Read an S-expression from a file that contains all of the data.
|
||||
;
|
||||
; The S-expression used for minor codes must have the structure
|
||||
; (package-name class-name exception-group-name
|
||||
; (exception
|
||||
; (name value level explanation)
|
||||
; ...
|
||||
; )
|
||||
; ...
|
||||
; )
|
||||
(define (read-file fname)
|
||||
(read (open-input-file fname)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Functions for handling major system exceptions and exception groups
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Function to find the base ID given an exception group name. Result is a function that
|
||||
; maps the minor code into the Java expression for that minor code's actual value.
|
||||
(define (get-base group-name)
|
||||
(if (eqv? group-name 'OMG)
|
||||
(lambda (minor-code)
|
||||
(string-append "OMGVMCID.value + " (number->string minor-code)))
|
||||
(let ; bind base-number outside the lambda so it is only evaluated once
|
||||
(
|
||||
(base-number (get-sun-base-number group-name)))
|
||||
(lambda (minor-code)
|
||||
(string-append "SUNVMCID.value + " (number->string (+ base-number minor-code)))))))
|
||||
|
||||
; Function to get a base value for the group-name
|
||||
(define (get-sun-base-number group-name)
|
||||
(let*
|
||||
(
|
||||
(lst (list 'SUNBASE 'ORBUTIL 'ACTIVATION 'NAMING 'INTERCEPTORS 'POA 'IOR 'UTIL))
|
||||
(subsystem-size 200))
|
||||
(* subsystem-size (get-list-position group-name lst))))
|
||||
|
||||
; Function to get a 3 digit number for a system exception
|
||||
(define (get-exception-id exception-name)
|
||||
(let
|
||||
(
|
||||
(lst (list 'UNKNOWN 'BAD_PARAM 'NO_MEMORY 'IMP_LIMIT 'COMM_FAILURE 'INV_OBJREF 'NO_PERMISSION
|
||||
'INTERNAL 'MARSHAL 'INITIALIZE 'NO_IMPLEMENT 'BAD_TYPECODE 'BAD_OPERATION 'NO_RESOURCES
|
||||
'NO_RESPONSE 'PERSIST_STORE 'BAD_INV_ORDER 'TRANSIENT 'FREE_MEM 'INV_IDENT 'INV_FLAG
|
||||
'INTF_REPOS 'BAD_CONTEXT 'OBJ_ADAPTER 'DATA_CONVERSION 'OBJECT_NOT_EXIST 'TRANSACTION_REQUIRED
|
||||
'TRANSACTION_ROLLEDBACK 'INVALID_TRANSACTION 'INV_POLICY 'CODESET_INCOMPATIBLE 'REBIND
|
||||
'TIMEOUT 'TRANSACTION_UNAVAILABLE 'BAD_QOS 'INVALID_ACTIVITY 'ACTIVITY_COMPLETED
|
||||
'ACTIVITY_REQUIRED )))
|
||||
(pad-number-string (get-list-position exception-name lst) 3)))
|
||||
|
||||
; Return the message id string for any system exception
|
||||
;
|
||||
(define (get-message-id exception-type group-name minor)
|
||||
(if (eqv? group-name 'OMG)
|
||||
(get-standard-message-id exception-type minor)
|
||||
(get-sun-message-id exception-type group-name minor)))
|
||||
|
||||
; Return the message id string for a particular standard exception
|
||||
;
|
||||
(define (get-standard-message-id exception-type minor)
|
||||
(string-append
|
||||
"IOP"
|
||||
(get-exception-id exception-type)
|
||||
"0"
|
||||
(pad-number-string (number->string minor) 4)))
|
||||
|
||||
; Return the sun message id for this exception-type, group-name, and minor code.
|
||||
(define (get-sun-message-id exception-type group-name minor)
|
||||
(string-append
|
||||
"IOP"
|
||||
(get-exception-id exception-type)
|
||||
"1"
|
||||
(pad-number-string (+ (get-sun-base-number group-name) minor) 4)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; visitor framework for the input file format
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (visit-top obj func1)
|
||||
(let*
|
||||
(
|
||||
(package (car obj))
|
||||
(class (cadr obj))
|
||||
(group (caddr obj))
|
||||
(func2 (func1 package class group))
|
||||
(exceptions (cadddr obj)))
|
||||
(visit-exceptions exceptions func2)))
|
||||
|
||||
; visit the elements of an arbitrary list
|
||||
; lst: the list to visit
|
||||
; func: the function to apply to each element of lst
|
||||
; next-level the function on lst element and func that visits the next level
|
||||
(define (visit-list lst func next-level)
|
||||
(if (null? (cdr lst))
|
||||
(next-level #t (car lst) func)
|
||||
(begin
|
||||
(next-level #f (car lst) func)
|
||||
(visit-list (cdr lst) func next-level))))
|
||||
|
||||
(define (visit-exceptions exceptions func2)
|
||||
(visit-list exceptions func2 (lambda (last-flag element func) (visit-exception last-flag element func))))
|
||||
|
||||
(define (visit-exception last-flag exception func2)
|
||||
(let*
|
||||
(
|
||||
(major (car exception))
|
||||
(minor-codes (cdr exception))
|
||||
(func3 (func2 last-flag major)))
|
||||
(visit-minor-codes minor-codes func3)))
|
||||
|
||||
(define (visit-minor-codes minor-codes func3)
|
||||
(visit-list minor-codes func3 (lambda (last-flag element func) (visit-minor-code last-flag element func))))
|
||||
|
||||
(define (visit-minor-code last-flag minor-code func3)
|
||||
(let*
|
||||
(
|
||||
(name (car minor-code))
|
||||
(minor (cadr minor-code))
|
||||
(level (caddr minor-code))
|
||||
(msg (cadddr minor-code)))
|
||||
(func3 last-flag name minor level msg)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; The visitors
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; A simple visitor that just echoes the input for test purposes
|
||||
(define (simple-visitor package class group)
|
||||
(let*
|
||||
(
|
||||
(pw (IndentingPrintWriter. System.out$)))
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.printMsg pw "package=@ class=@ group=@" (list package class group))
|
||||
(.flush pw)
|
||||
(lambda (last-flag major)
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.printMsg pw "major=@" (list major))
|
||||
(.flush pw)
|
||||
(lambda (last-flag name minor level message)
|
||||
(begin
|
||||
(if last-flag (.undent pw))
|
||||
(.printMsg pw "name=@ minor=@ level=@ message=@" (list name minor level message))
|
||||
(.flush pw))))))))
|
||||
|
||||
; Function that returns a visitor that writes out the resource file in the form:
|
||||
; id="MSGID: explanation"
|
||||
; outdir: Output directory
|
||||
(define (resource-visitor outdir)
|
||||
(lambda (package class group)
|
||||
(let*
|
||||
(
|
||||
(file-name (string-append outdir java.io.File.separator$ class ".resource"))
|
||||
(pw (IndentingPrintWriter. (FileOutputStream. file-name))))
|
||||
(begin
|
||||
(dprint (string-append "package= " package " class=" class " group=" group " file-name=" file-name))
|
||||
(lambda (last-flag1 major)
|
||||
(begin
|
||||
; (dprint (string-append "last-flag1=" last-flag1 " major=" major))
|
||||
(lambda (last-flag2 name minor level message)
|
||||
(begin
|
||||
; (dprint (string-append "last-flag2=" last-flag2 " name=" name
|
||||
; " minor=" minor " level=" level " message=" message))
|
||||
(let*
|
||||
(
|
||||
(msgid (get-message-id major group minor))
|
||||
(ident (StringUtil.toMixedCase (symbol->string name))))
|
||||
(begin
|
||||
; (dprint (string-append "msgid=" msgid " ident=" ident))
|
||||
(.printMsg pw "@.@=\"@: (@) @\"" (list group ident msgid major message))
|
||||
(.flush pw)
|
||||
(if (and last-flag1 last-flag2)
|
||||
(begin
|
||||
; (dprint "closing file")
|
||||
(.close pw)))))))))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Top-level functions for creating the products. All have names of the form make-xxx
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Read the minor codes from the infile and write out a resource file.
|
||||
(define (make-resource infile outdir)
|
||||
(tryCatch
|
||||
(visit-top (read-file infile) (resource-visitor outdir))
|
||||
(lambda (exc)
|
||||
(begin
|
||||
(.println System.out$ (string-append "make-resource failed with exception " (.toString exc)))
|
||||
(System.exit 1)))))
|
||||
|
||||
; Read the minor codes from the infile and write a Java implementation to
|
||||
; handle them to outfile under outdir
|
||||
(define (make-class infile outdir)
|
||||
(tryCatch
|
||||
(write-class infile outdir (read-file infile))
|
||||
(lambda (exc)
|
||||
(begin
|
||||
(.println System.out$ (string-append "make-class failed with exception " (.toString exc)))
|
||||
(System.exit 1)))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; The original make-class implementation (this should be replaced by two visitors)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Write out the Java source code for the StandardExceptions class
|
||||
; outdir: Output directory to write the generated files
|
||||
; obj: the data from the input file
|
||||
(define (write-class infile outdir obj)
|
||||
(let*
|
||||
(
|
||||
(package-name (car obj))
|
||||
(class-name (cadr obj))
|
||||
(exception-group-name (caddr obj))
|
||||
(exceptions (cadddr obj))
|
||||
(file (FileOutputStream. (string-append outdir java.io.File.separator$ class-name ".java")))
|
||||
(pw (IndentingPrintWriter. file))
|
||||
)
|
||||
(begin
|
||||
(write-class-header infile package-name class-name exception-group-name pw)
|
||||
(.printMsg pw "package @ ;"
|
||||
(list package-name))
|
||||
(.println pw)
|
||||
(.println pw "import java.util.logging.Logger ;")
|
||||
(.println pw "import java.util.logging.Level ;")
|
||||
(.println pw)
|
||||
(.println pw "import org.omg.CORBA.OMGVMCID ;")
|
||||
(.println pw "import com.sun.corba.se.impl.util.SUNVMCID ;")
|
||||
(.println pw "import org.omg.CORBA.CompletionStatus ;")
|
||||
(.println pw "import org.omg.CORBA.SystemException ;")
|
||||
(.println pw)
|
||||
(.println pw "import com.sun.corba.se.spi.orb.ORB ;")
|
||||
(.println pw)
|
||||
(.println pw "import com.sun.corba.se.spi.logging.LogWrapperFactory;")
|
||||
(.println pw)
|
||||
(.println pw "import com.sun.corba.se.spi.logging.LogWrapperBase;")
|
||||
(.println pw)
|
||||
(write-imports exceptions pw)
|
||||
(.println pw)
|
||||
(.indent pw)
|
||||
(.printMsg pw "public class @ extends LogWrapperBase {"
|
||||
(list class-name))
|
||||
(.println pw)
|
||||
(.printMsg pw "public @( Logger logger )"
|
||||
(list class-name))
|
||||
(.indent pw)
|
||||
(.println pw "{")
|
||||
(.undent pw)
|
||||
(.println pw "super( logger ) ;")
|
||||
(.println pw "}")
|
||||
(.println pw)
|
||||
(.flush pw)
|
||||
(write-factory-method class-name exception-group-name pw)
|
||||
(write-exceptions exception-group-name exceptions (get-base exception-group-name) class-name pw)
|
||||
(.undent pw)
|
||||
(.println pw )
|
||||
(.println pw "}")
|
||||
(.flush pw)
|
||||
(.close pw)
|
||||
)))
|
||||
|
||||
; Write out the header for the resource file
|
||||
(define (write-class-header infile package class group pw)
|
||||
(begin
|
||||
(if (eqv? group 'OMG)
|
||||
(.println pw "// Log wrapper class for standard exceptions")
|
||||
(.printMsg pw "// Log wrapper class for Sun private system exceptions in group @" (list group)))
|
||||
(.println pw "//")
|
||||
(.printMsg pw "// Generated by mc.scm version @, DO NOT EDIT BY HAND!" (list version-string))
|
||||
(.printMsg pw "// Generated from input file @ on @" (list infile (java.util.Date.)))
|
||||
(.println pw)))
|
||||
|
||||
(define (write-factory-method class-name exception-group-name pw)
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.println pw "private static LogWrapperFactory factory = new LogWrapperFactory() {")
|
||||
(.println pw "public LogWrapperBase create( Logger logger )" )
|
||||
(.indent pw)
|
||||
(.println pw "{")
|
||||
(.undent pw)
|
||||
(.printMsg pw "return new @( logger ) ;" (list class-name))
|
||||
(.undent pw)
|
||||
(.println pw "}" )
|
||||
(.println pw "} ;" )
|
||||
(.println pw)
|
||||
(.printMsg pw "public static @ get( ORB orb, String logDomain )" (list class-name))
|
||||
(.indent pw)
|
||||
(.println pw "{")
|
||||
(.indent pw)
|
||||
(.printMsg pw "@ wrapper = "
|
||||
(list class-name))
|
||||
(.indent pw)
|
||||
(.printMsg pw "(@) orb.getLogWrapper( logDomain, "
|
||||
(list class-name))
|
||||
(.undent pw)
|
||||
(.undent pw)
|
||||
(.printMsg pw "\"@\", factory ) ;"
|
||||
(list exception-group-name))
|
||||
(.undent pw)
|
||||
(.println pw "return wrapper ;" )
|
||||
(.println pw "} " )
|
||||
(.println pw)
|
||||
(.printMsg pw "public static @ get( String logDomain )" (list class-name))
|
||||
(.indent pw)
|
||||
(.println pw "{")
|
||||
(.indent pw)
|
||||
(.printMsg pw "@ wrapper = "
|
||||
(list class-name))
|
||||
(.indent pw)
|
||||
(.printMsg pw "(@) ORB.staticGetLogWrapper( logDomain, "
|
||||
(list class-name))
|
||||
(.undent pw)
|
||||
(.undent pw)
|
||||
(.printMsg pw "\"@\", factory ) ;"
|
||||
(list exception-group-name))
|
||||
(.undent pw)
|
||||
(.println pw "return wrapper ;" )
|
||||
(.println pw "} " )
|
||||
(.println pw)))
|
||||
|
||||
; Write out the import list for the exceptions listed in obj
|
||||
; obj: the data from the input file
|
||||
; pw: an IndentingPrintWriter for the output file
|
||||
(define (write-imports obj pw)
|
||||
(if (null? obj)
|
||||
()
|
||||
(let
|
||||
(
|
||||
(exception (caar obj))
|
||||
)
|
||||
(begin
|
||||
(.print pw "import org.omg.CORBA.")
|
||||
(.print pw exception)
|
||||
(.println pw " ;")
|
||||
(write-imports (cdr obj) pw)
|
||||
))))
|
||||
|
||||
; Write out the list of exceptions starting with the first one
|
||||
; obj: the data from the input file
|
||||
; base: the lambda that returns the string defining the minor code value
|
||||
; pw: an IndentingPrintWriter for the output file
|
||||
(define (write-exceptions group-name obj base class-name pw)
|
||||
(if (null? obj)
|
||||
()
|
||||
(let*
|
||||
(
|
||||
(record (car obj))
|
||||
(exception (car record))
|
||||
(minor-codes (cdr record))
|
||||
)
|
||||
(begin
|
||||
(write-exception group-name exception minor-codes base class-name pw)
|
||||
(write-exceptions group-name (cdr obj) base class-name pw)
|
||||
))))
|
||||
|
||||
; Write out a single exception
|
||||
; exception: the CORBA SystemException type
|
||||
; base: the base for the minor code value
|
||||
; minor-codes: a list of minor code data for each minor exception type
|
||||
; pw: an IndentingPrintWriter for the output file
|
||||
(define (write-exception group-name exception minor-codes base class-name pw)
|
||||
(begin
|
||||
(.println pw "///////////////////////////////////////////////////////////")
|
||||
(.printMsg pw "// @" (list exception))
|
||||
(.println pw "///////////////////////////////////////////////////////////")
|
||||
(.println pw)
|
||||
(write-methods group-name exception minor-codes base class-name pw)
|
||||
(.flush pw)))
|
||||
|
||||
; Write all of the methods for a single exception
|
||||
; exception: the CORBA SystemException type
|
||||
; base: the base for the minor code value
|
||||
; minor-codes: a list of minor code data for each minor exception type
|
||||
; pw: an IndentingPrintWriter for the output file
|
||||
(define (write-methods group-name exception minor-codes base class-name pw)
|
||||
(if (null? minor-codes)
|
||||
()
|
||||
(begin
|
||||
(write-method group-name exception (car minor-codes) base class-name pw)
|
||||
(write-methods group-name exception (cdr minor-codes) base class-name pw)
|
||||
)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Code that writes out the Java methods for exception handling
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Write the methods for a single minor code within an exception
|
||||
; exception: the CORBA SystemException type
|
||||
; minor-code: minor code data for one minor exception type
|
||||
; (name value level explanation)
|
||||
; base: the base for the minor code value
|
||||
; pw: an IndentingPrintWriter for the output file
|
||||
(define (write-method group-name exception minor-code base class-name pw)
|
||||
(let*
|
||||
(
|
||||
(x (symbol->string (car minor-code)))
|
||||
(ident (cons x (StringUtil.toMixedCase x)))
|
||||
(value (cadr minor-code))
|
||||
(level (symbol->string (caddr minor-code)))
|
||||
(explanation (cadddr minor-code))
|
||||
(num-params (StringUtil.countArgs explanation)))
|
||||
(begin
|
||||
(.printMsg pw "public static final int @ = @ ;"
|
||||
(list x (base value)))
|
||||
(.println pw )
|
||||
(.flush pw )
|
||||
(write-method-status-cause group-name exception ident level num-params class-name pw)
|
||||
(.println pw)
|
||||
(.flush pw)
|
||||
(write-method-status exception ident level num-params pw)
|
||||
(.println pw)
|
||||
(.flush pw)
|
||||
(write-method-cause exception ident level num-params pw)
|
||||
(.println pw)
|
||||
(.flush pw)
|
||||
(write-method-no-args exception ident level num-params pw)
|
||||
(.println pw)
|
||||
(.flush pw))))
|
||||
|
||||
; Construct a string of the form arg1, ..., argn where n is num-params
|
||||
(define (make-arg-string fixed leading-comma-flag num-args)
|
||||
(let
|
||||
(
|
||||
(helper (lambda (lcf n)
|
||||
(let*
|
||||
(
|
||||
(numstr (number->string (- n 1))))
|
||||
(if (or lcf (> n 1))
|
||||
(string-append ", " fixed numstr)
|
||||
(string-append " " fixed numstr))))))
|
||||
(cond
|
||||
((eqv? num-args 0) " ")
|
||||
((eqv? num-args 1) (helper leading-comma-flag 1))
|
||||
(else (string-append
|
||||
(make-arg-string fixed leading-comma-flag (- num-args 1))
|
||||
(helper leading-comma-flag num-args ))))))
|
||||
|
||||
(define (make-decl-args leading-comma-flag num-args)
|
||||
(make-arg-string "Object arg" leading-comma-flag num-args))
|
||||
|
||||
(define (make-call-args leading-comma-flag num-args)
|
||||
(make-arg-string "arg" leading-comma-flag num-args))
|
||||
|
||||
; make-xxx-args patterns:
|
||||
; leading-comma-flag #t
|
||||
;
|
||||
; 0 " "
|
||||
; 1 ", arg0"
|
||||
; 2 ", arg0, arg1"
|
||||
; 3 ", arg0, arg1, arg2"
|
||||
;
|
||||
; 0 " "
|
||||
; 1 ", Object arg0"
|
||||
; 2 ", Object arg0, Object arg1"
|
||||
; 3 ", Object arg0, Object arg1, Object arg2"
|
||||
;
|
||||
; leading-comma-flag #f
|
||||
;
|
||||
; 0 " "
|
||||
; 1 " arg0"
|
||||
; 2 " arg0, arg1"
|
||||
; 3 " arg0, arg1, arg2"
|
||||
;
|
||||
; 0 " "
|
||||
; 1 " Object arg0"
|
||||
; 2 " Object arg0, Object arg1"
|
||||
; 3 " Object arg0, Object arg1, Object arg2"
|
||||
|
||||
(define (emit-assignments num pw)
|
||||
(let
|
||||
(
|
||||
(helper
|
||||
(lambda (n)
|
||||
(.printMsg pw "parameters[@] = arg@ ;" (list n n)))))
|
||||
(if (= num 1)
|
||||
(helper (- num 1))
|
||||
(begin
|
||||
(emit-assignments (- num 1) pw)
|
||||
(helper (- num 1))))))
|
||||
|
||||
; Write a method for an exception that takes a CompletionStatus and a cause
|
||||
; exception: the CORBA system exception type
|
||||
; id: the identifier for this exception in the form ( ident . mixed-case-ident )
|
||||
; level: the logging level
|
||||
; num-params: number of parameters in the explanation string, which determines
|
||||
; how many argn parameters we need
|
||||
; pw: the indenting print writer we are using
|
||||
(define (write-method-status-cause group-name exception id level num-params class-name pw)
|
||||
(let*
|
||||
(
|
||||
(ident (car id))
|
||||
(ident-mc (cdr id)))
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.printMsg pw "public @ @( CompletionStatus cs, Throwable t@) {"
|
||||
(list exception ident-mc (make-decl-args #t num-params)))
|
||||
(.printMsg pw "@ exc = new @( @, cs ) ;"
|
||||
(list exception exception ident ))
|
||||
|
||||
(.indent pw)
|
||||
(.println pw "if (t != null)" )
|
||||
(.undent pw)
|
||||
(.println pw "exc.initCause( t ) ;" )
|
||||
(.println pw)
|
||||
|
||||
(.indent pw)
|
||||
(.printMsg pw "if (logger.isLoggable( Level.@ )) {"
|
||||
(list level))
|
||||
|
||||
(if (> num-params 0)
|
||||
(begin
|
||||
(.printMsg pw "Object[] parameters = new Object[@] ;"
|
||||
(list (number->string num-params)))
|
||||
(emit-assignments num-params pw)
|
||||
)
|
||||
(begin
|
||||
(.println pw "Object[] parameters = null ;"
|
||||
)))
|
||||
|
||||
(.indent pw)
|
||||
(.printMsg pw "doLog( Level.@, \"@.@\"," (list level group-name ident-mc))
|
||||
(.undent pw)
|
||||
(.undent pw)
|
||||
(.printMsg pw "parameters, @.class, exc ) ;" (list class-name))
|
||||
(.println pw "}")
|
||||
(.println pw)
|
||||
|
||||
(.undent pw)
|
||||
(.println pw "return exc ;")
|
||||
|
||||
(.println pw "}"))))
|
||||
|
||||
; Write a method for an exception that takes a CompletionStatus. The cause is null.
|
||||
;
|
||||
; exception: the CORBA system exception type
|
||||
; id: the identifier for this exception in the form ( ident . mixed-case-ident )
|
||||
; level: the logging level
|
||||
; num-params: number of parameters in the explanation string, which determines
|
||||
; how many argn parameters we need
|
||||
; pw: the indenting print writer we are using
|
||||
(define (write-method-status exception id level num-params pw)
|
||||
(let*
|
||||
(
|
||||
(ident-mc (cdr id)))
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.printMsg pw "public @ @( CompletionStatus cs@) {"
|
||||
(list exception ident-mc (make-decl-args #t num-params)))
|
||||
(.undent pw)
|
||||
(.printMsg pw "return @( cs, null@ ) ;"
|
||||
(list ident-mc (make-call-args #t num-params)))
|
||||
(.println pw "}"))))
|
||||
|
||||
; Write a method for an exception that takes a cause. The status is COMPLETED_NO.
|
||||
;
|
||||
; exception: the CORBA system exception type
|
||||
; id: the identifier for this exception in the form ( ident . mixed-case-ident )
|
||||
; level: the logging level
|
||||
; num-params: number of parameters in the explanation string, which determines
|
||||
; how many argn parameters we need
|
||||
; pw: the indenting print writer we are using
|
||||
(define (write-method-cause exception id level num-params pw)
|
||||
(let*
|
||||
(
|
||||
(ident-mc (cdr id)))
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.printMsg pw "public @ @( Throwable t@) {"
|
||||
(list exception ident-mc (make-decl-args #t num-params)))
|
||||
(.undent pw)
|
||||
(.printMsg pw "return @( CompletionStatus.COMPLETED_NO, t@ ) ;"
|
||||
(list ident-mc (make-call-args #t num-params)))
|
||||
(.println pw "}"))))
|
||||
|
||||
; Write a method for an exception that takes no arguments. This is COMPLETED_NO and
|
||||
; a null cause.
|
||||
;
|
||||
; exception: the CORBA system exception type
|
||||
; id: the identifier for this exception in the form ( ident . mixed-case-ident )
|
||||
; level: the logging level
|
||||
; num-params: number of parameters in the explanation string, which determines
|
||||
; how many argn parameters we need
|
||||
; pw: the indenting print writer we are using
|
||||
(define (write-method-no-args exception id level num-params pw)
|
||||
(let*
|
||||
(
|
||||
(ident-mc (cdr id)))
|
||||
(begin
|
||||
(.indent pw)
|
||||
(.printMsg pw "public @ @( @) {"
|
||||
(list exception ident-mc (make-decl-args #f num-params)))
|
||||
(.undent pw)
|
||||
(.printMsg pw "return @( CompletionStatus.COMPLETED_NO, null@ ) ;"
|
||||
(list ident-mc (make-call-args #t num-params)))
|
||||
(.println pw "}"))))
|
||||
|
||||
;;; end of file
|
@ -1,2 +0,0 @@
|
||||
#! /bin/sh
|
||||
java -cp ${CLASSPATH}:lib/jscheme.jar:lib/util.jar jscheme.REPL mc.scm
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 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
|
||||
|
@ -23,7 +23,7 @@
|
||||
// have any questions.
|
||||
//
|
||||
|
||||
#include "afxres.h"
|
||||
#include "windows.h"
|
||||
|
||||
// Need 2 defines so macro argument to XSTR will get expanded before quoting.
|
||||
#define XSTR(x) STR(x)
|
||||
|
@ -23,3 +23,9 @@ fc6a5ae3fef5ebacfa896dbb3ae37715e388e282 jdk7-b43
|
||||
16bb38eeda35b46268eefa4c1f829eb086e0ca46 jdk7-b46
|
||||
fcb923bad68e2b10380a030ea83a723f4dc3d4d6 jdk7-b47
|
||||
bcb33806d186561c781992e5f4d8a90bb033f9f0 jdk7-b48
|
||||
8b22ccb5aba2c6c11bddf6488a7bb7ef5b4bf2be jdk7-b49
|
||||
dae503d9f04c1a11e182dbf7f770509c28dc0609 jdk7-b50
|
||||
2581d90c6c9b2012da930eb4742add94a03069a0 jdk7-b51
|
||||
1b1e8f1a4fe8cebc01c022484f78148e17b62a0d jdk7-b52
|
||||
032c6af894dae8d939b3dd31d82042549e7793e0 jdk7-b53
|
||||
fafab5d5349c7c066d677538db67a1ee0fb33bd2 jdk7-b54
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2009 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
|
||||
|
@ -118,9 +118,9 @@ public interface Debugger extends SymbolLookup, ThreadAccess {
|
||||
public long getJIntSize();
|
||||
public long getJLongSize();
|
||||
public long getJShortSize();
|
||||
public long getHeapBase();
|
||||
public long getHeapOopSize();
|
||||
public long getLogMinObjAlignmentInBytes();
|
||||
public long getNarrowOopBase();
|
||||
public int getNarrowOopShift();
|
||||
|
||||
public ReadResult readBytesFromProcess(long address, long numBytes)
|
||||
throws DebuggerException;
|
||||
|
@ -56,8 +56,8 @@ public abstract class DebuggerBase implements Debugger {
|
||||
// heap data.
|
||||
protected long oopSize;
|
||||
protected long heapOopSize;
|
||||
protected long heapBase; // heap base for compressed oops.
|
||||
protected long logMinObjAlignmentInBytes; // Used to decode compressed oops.
|
||||
protected long narrowOopBase; // heap base for compressed oops.
|
||||
protected int narrowOopShift; // shift to decode compressed oops.
|
||||
// Should be initialized if desired by calling initCache()
|
||||
private PageCache cache;
|
||||
|
||||
@ -159,10 +159,10 @@ public abstract class DebuggerBase implements Debugger {
|
||||
javaPrimitiveTypesConfigured = true;
|
||||
}
|
||||
|
||||
public void putHeapConst(long heapBase, long heapOopSize, long logMinObjAlignmentInBytes) {
|
||||
this.heapBase = heapBase;
|
||||
public void putHeapConst(long heapOopSize, long narrowOopBase, int narrowOopShift) {
|
||||
this.heapOopSize = heapOopSize;
|
||||
this.logMinObjAlignmentInBytes = logMinObjAlignmentInBytes;
|
||||
this.narrowOopBase = narrowOopBase;
|
||||
this.narrowOopShift = narrowOopShift;
|
||||
}
|
||||
|
||||
/** May be called by subclasses if desired to initialize the page
|
||||
@ -459,7 +459,7 @@ public abstract class DebuggerBase implements Debugger {
|
||||
long value = readCInteger(address, getHeapOopSize(), true);
|
||||
if (value != 0) {
|
||||
// See oop.inline.hpp decode_heap_oop
|
||||
value = (long)(heapBase + (long)(value << logMinObjAlignmentInBytes));
|
||||
value = (long)(narrowOopBase + (long)(value << narrowOopShift));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -545,10 +545,10 @@ public abstract class DebuggerBase implements Debugger {
|
||||
return heapOopSize;
|
||||
}
|
||||
|
||||
public long getHeapBase() {
|
||||
return heapBase;
|
||||
public long getNarrowOopBase() {
|
||||
return narrowOopBase;
|
||||
}
|
||||
public long getLogMinObjAlignmentInBytes() {
|
||||
return logMinObjAlignmentInBytes;
|
||||
public int getNarrowOopShift() {
|
||||
return narrowOopShift;
|
||||
}
|
||||
}
|
||||
|
@ -42,5 +42,5 @@ public interface JVMDebugger extends Debugger {
|
||||
long jintSize,
|
||||
long jlongSize,
|
||||
long jshortSize);
|
||||
public void putHeapConst(long heapBase, long heapOopSize, long logMinObjAlignment);
|
||||
public void putHeapConst(long heapOopSize, long narrowOopBase, int narrowOopShift);
|
||||
}
|
||||
|
@ -65,9 +65,10 @@ public interface RemoteDebugger extends Remote {
|
||||
public long getJIntSize() throws RemoteException;
|
||||
public long getJLongSize() throws RemoteException;
|
||||
public long getJShortSize() throws RemoteException;
|
||||
public long getHeapBase() throws RemoteException;
|
||||
public long getHeapOopSize() throws RemoteException;
|
||||
public long getLogMinObjAlignmentInBytes() throws RemoteException;
|
||||
public long getNarrowOopBase() throws RemoteException;
|
||||
public int getNarrowOopShift() throws RemoteException;
|
||||
|
||||
public boolean areThreadsEqual(long addrOrId1, boolean isAddress1,
|
||||
long addrOrId2, boolean isAddress2) throws RemoteException;
|
||||
public int getThreadHashCode(long addrOrId, boolean isAddress) throws RemoteException;
|
||||
|
@ -85,9 +85,9 @@ public class RemoteDebuggerClient extends DebuggerBase implements JVMDebugger {
|
||||
jlongSize = remoteDebugger.getJLongSize();
|
||||
jshortSize = remoteDebugger.getJShortSize();
|
||||
javaPrimitiveTypesConfigured = true;
|
||||
heapBase = remoteDebugger.getHeapBase();
|
||||
narrowOopBase = remoteDebugger.getNarrowOopBase();
|
||||
narrowOopShift = remoteDebugger.getNarrowOopShift();
|
||||
heapOopSize = remoteDebugger.getHeapOopSize();
|
||||
logMinObjAlignmentInBytes = remoteDebugger.getLogMinObjAlignmentInBytes();
|
||||
}
|
||||
catch (RemoteException e) {
|
||||
throw new DebuggerException(e);
|
||||
|
@ -114,17 +114,18 @@ public class RemoteDebuggerServer extends UnicastRemoteObject
|
||||
return debugger.getJShortSize();
|
||||
}
|
||||
|
||||
public long getHeapBase() throws RemoteException {
|
||||
return debugger.getHeapBase();
|
||||
}
|
||||
|
||||
public long getHeapOopSize() throws RemoteException {
|
||||
return debugger.getHeapOopSize();
|
||||
}
|
||||
|
||||
public long getLogMinObjAlignmentInBytes() throws RemoteException {
|
||||
return debugger.getLogMinObjAlignmentInBytes();
|
||||
public long getNarrowOopBase() throws RemoteException {
|
||||
return debugger.getNarrowOopBase();
|
||||
}
|
||||
|
||||
public int getNarrowOopShift() throws RemoteException {
|
||||
return debugger.getNarrowOopShift();
|
||||
}
|
||||
|
||||
public boolean areThreadsEqual(long addrOrId1, boolean isAddress1,
|
||||
long addrOrId2, boolean isAddress2) throws RemoteException {
|
||||
ThreadProxy t1 = getThreadProxy(addrOrId1, isAddress1);
|
||||
|
@ -53,7 +53,8 @@ public class Universe {
|
||||
// system obj array klass object
|
||||
private static sun.jvm.hotspot.types.OopField systemObjArrayKlassObjField;
|
||||
|
||||
private static AddressField heapBaseField;
|
||||
private static AddressField narrowOopBaseField;
|
||||
private static CIntegerField narrowOopShiftField;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
@ -86,7 +87,8 @@ public class Universe {
|
||||
|
||||
systemObjArrayKlassObjField = type.getOopField("_systemObjArrayKlassObj");
|
||||
|
||||
heapBaseField = type.getAddressField("_heap_base");
|
||||
narrowOopBaseField = type.getAddressField("_narrow_oop._base");
|
||||
narrowOopShiftField = type.getCIntegerField("_narrow_oop._shift");
|
||||
}
|
||||
|
||||
public Universe() {
|
||||
@ -100,14 +102,18 @@ public class Universe {
|
||||
}
|
||||
}
|
||||
|
||||
public static long getHeapBase() {
|
||||
if (heapBaseField.getValue() == null) {
|
||||
public static long getNarrowOopBase() {
|
||||
if (narrowOopBaseField.getValue() == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return heapBaseField.getValue().minus(null);
|
||||
return narrowOopBaseField.getValue().minus(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getNarrowOopShift() {
|
||||
return (int)narrowOopShiftField.getValue();
|
||||
}
|
||||
|
||||
/** Returns "TRUE" iff "p" points into the allocated area of the heap. */
|
||||
public boolean isIn(Address p) {
|
||||
return heap().isIn(p);
|
||||
|
@ -46,12 +46,18 @@ public class StubRoutines {
|
||||
Type type = db.lookupType("StubRoutines");
|
||||
|
||||
callStubReturnAddressField = type.getAddressField("_call_stub_return_address");
|
||||
// Only some platforms have specif return from compiled to call_stub
|
||||
// Only some platforms have specific return from compiled to call_stub
|
||||
try {
|
||||
type = db.lookupType("StubRoutines::x86");
|
||||
if (type != null) {
|
||||
callStubCompiledReturnAddressField = type.getAddressField("_call_stub_compiled_return");
|
||||
}
|
||||
} catch (RuntimeException re) {
|
||||
callStubCompiledReturnAddressField = null;
|
||||
}
|
||||
if (callStubCompiledReturnAddressField == null && VM.getVM().getCPU().equals("x86")) {
|
||||
throw new InternalError("Missing definition for _call_stub_compiled_return");
|
||||
}
|
||||
}
|
||||
|
||||
public StubRoutines() {
|
||||
|
@ -342,11 +342,14 @@ public class VM {
|
||||
throw new RuntimeException("Attempt to initialize VM twice");
|
||||
}
|
||||
soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
|
||||
debugger.putHeapConst(Universe.getHeapBase(), soleInstance.getHeapOopSize(),
|
||||
soleInstance.logMinObjAlignmentInBytes);
|
||||
|
||||
debugger.putHeapConst(soleInstance.getHeapOopSize(), Universe.getNarrowOopBase(),
|
||||
Universe.getNarrowOopShift());
|
||||
|
||||
for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
|
||||
((Observer) iter.next()).update(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** This is used by the debugging system */
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2006-2009 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
|
||||
@ -31,11 +31,11 @@
|
||||
#
|
||||
|
||||
# Don't put quotes (fail windows build).
|
||||
HOTSPOT_VM_COPYRIGHT=Copyright 2008
|
||||
HOTSPOT_VM_COPYRIGHT=Copyright 2009
|
||||
|
||||
HS_MAJOR_VER=15
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=02
|
||||
HS_BUILD_NUMBER=05
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=7
|
||||
|
@ -89,60 +89,52 @@ jprt.my.solaris.sparc.test.targets= \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
|
||||
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
|
||||
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp, \
|
||||
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp_2, \
|
||||
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp_3, \
|
||||
${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default_2, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC_2, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC_2, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC_2, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS_2, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_default, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_CMS, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_G1, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParOldGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_default, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_CMS, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark_2, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark_3
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_G1, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParOldGC
|
||||
|
||||
jprt.my.solaris.sparcv9.test.targets= \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
|
||||
${jprt.my.solaris.sparcv9}-product-c2-runThese, \
|
||||
${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp, \
|
||||
${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp_2, \
|
||||
${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp_3, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default_2, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS_2, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_G1, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_default, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_SerialGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParallelGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParNewGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_CMS, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_G1, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParOldGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark_2, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark_3
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_G1, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParOldGC
|
||||
|
||||
jprt.my.solaris.x64.test.targets= \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \
|
||||
@ -154,73 +146,80 @@ jprt.my.solaris.x64.test.targets= \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_default_2, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS_2, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_G1, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_default, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_CMS
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC
|
||||
|
||||
jprt.my.solaris.i586.test.targets= \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark, \
|
||||
${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
|
||||
${jprt.my.solaris.i586}-product-c2-runThese_Xcomp_2, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp_2, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xshare, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_default, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_CMS, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_G1, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_default, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_SerialGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_CMS, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_G1, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_default, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_SerialGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_ParNewGC, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_CMS, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_G1, \
|
||||
${jprt.my.solaris.i586}-product-c1-GCOld_ParOldGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_default, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark_2, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark_3
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_G1, \
|
||||
${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParOldGC
|
||||
|
||||
jprt.my.linux.i586.test.targets = \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \
|
||||
${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
|
||||
${jprt.my.linux.i586}-product-c1-runThese_Xcomp_2, \
|
||||
${jprt.my.linux.i586}-product-c1-runThese_Xcomp_3, \
|
||||
${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
|
||||
${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp, \
|
||||
${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp_2, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_default, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_SerialGC, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParallelGC, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParNewGC, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_CMS, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_G1, \
|
||||
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParOldGC, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_default, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c2-scimark_2, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c2-scimark_3
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_G1, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParOldGC
|
||||
|
||||
jprt.my.linux.x64.test.targets = \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
|
||||
@ -230,15 +229,19 @@ jprt.my.linux.x64.test.targets = \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_G1, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_default, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_CMS, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_G1, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark_2, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark_3
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParOldGC
|
||||
|
||||
jprt.my.windows.i586.test.targets = \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
|
||||
@ -251,16 +254,20 @@ jprt.my.windows.i586.test.targets = \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_default, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_SerialGC, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParallelGC, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParNewGC, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_CMS, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_G1, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParOldGC, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-scimark_2, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-scimark_3
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-jbb_G1, \
|
||||
${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParOldGC
|
||||
|
||||
jprt.my.windows.x64.test.targets = \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \
|
||||
@ -272,16 +279,20 @@ jprt.my.windows.x64.test.targets = \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_G1, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_default, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_CMS, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_G1, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \
|
||||
${jprt.my.windows.x64}-product-c2-jbb_CMS, \
|
||||
${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark_2, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark_3
|
||||
${jprt.my.windows.x64}-product-c2-jbb_G1, \
|
||||
${jprt.my.windows.x64}-product-c2-jbb_ParOldGC
|
||||
|
||||
# The complete list of test targets for jprt
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1999-2009 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
|
||||
@ -61,8 +61,8 @@ CPPFLAGS = $(SYSDEFS) $(INCLUDES)
|
||||
CPPFLAGS += -DASSERT
|
||||
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
# Suppress warnings (for now)
|
||||
CFLAGS_WARN = -w
|
||||
# Compiler warnings are treated as errors
|
||||
CFLAGS_WARN = -Werror
|
||||
CFLAGS += $(CFLAGS_WARN)
|
||||
|
||||
OBJECTNAMES = \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1999-2009 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
|
||||
@ -131,6 +131,14 @@ endif
|
||||
# Enable linker optimization
|
||||
LFLAGS += -Xlinker -O1
|
||||
|
||||
# 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 += $(LDFLAGS_HASH_STYLE)
|
||||
|
||||
# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
|
||||
MAPFLAG = -Xlinker --version-script=FILENAME
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1997-2009 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
|
||||
@ -67,6 +67,8 @@ ifndef USE_GCC
|
||||
endif
|
||||
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
# Compiler warnings are treated as errors
|
||||
CFLAGS_WARN = +w -errwarn
|
||||
CFLAGS += $(CFLAGS_WARN)
|
||||
|
||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||
|
@ -52,6 +52,19 @@ CAT="$MKS_HOME/cat.exe"
|
||||
RM="$MKS_HOME/rm.exe"
|
||||
DUMPBIN="link.exe /dump"
|
||||
|
||||
# When called from IDE the first param should contain the link version, otherwise may be nill
|
||||
if [ "x$1" != "x" ]; then
|
||||
LINK_VER="$1"
|
||||
fi
|
||||
|
||||
if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" ]; then
|
||||
$DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
|
||||
else
|
||||
# Can't use pipes when calling cl.exe or link.exe from IDE. Using transit file vm3.def
|
||||
$DUMPBIN /OUT:vm3.def /symbols *.obj
|
||||
"$CAT" vm3.def | "$GREP" "??_7.*@@6B@" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
|
||||
"$RM" -f vm3.def
|
||||
fi
|
||||
|
||||
"$CAT" vm1.def vm2.def > vm.def
|
||||
"$RM" -f vm1.def vm2.def
|
||||
|
@ -72,12 +72,20 @@ REM figure out MSC version
|
||||
for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
|
||||
|
||||
echo **************************************************************
|
||||
set ProjectFile=vm.vcproj
|
||||
if "%MSC_VER%" == "1200" (
|
||||
set ProjectFile=vm.dsp
|
||||
echo Will generate VC6 project {unsupported}
|
||||
) else (
|
||||
set ProjectFile=vm.vcproj
|
||||
echo Will generate VC7 project
|
||||
if "%MSC_VER%" == "1400" (
|
||||
echo Will generate VC8 {Visual Studio 2005}
|
||||
) else (
|
||||
if "%MSC_VER%" == "1500" (
|
||||
echo Will generate VC9 {Visual Studio 2008}
|
||||
) else (
|
||||
echo Will generate VC7 project {Visual Studio 2003 .NET}
|
||||
)
|
||||
)
|
||||
)
|
||||
echo %ProjectFile%
|
||||
echo **************************************************************
|
||||
|
@ -29,6 +29,7 @@
|
||||
# cl version 13.10.3077 returns "MSC_VER=1310"
|
||||
# cl version 14.00.30701 returns "MSC_VER=1399" (OLD_MSSDK version)
|
||||
# cl version 14.00.40310.41 returns "MSC_VER=1400"
|
||||
# cl version 15.00.21022.8 returns "MSC_VER=1500"
|
||||
|
||||
# Note that we currently do not have a way to set HotSpotMksHome in
|
||||
# the batch build, but so far this has not seemed to be a problem. The
|
||||
|
@ -46,6 +46,7 @@ ADLCFLAGS=-q -T -D_LP64
|
||||
ADLCFLAGS=-q -T -U_LP64
|
||||
!endif
|
||||
|
||||
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
CPP_INCLUDE_DIRS=\
|
||||
/I "..\generated" \
|
||||
|
@ -170,10 +170,6 @@ LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
|
||||
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||
# as resources inside build artifacts.
|
||||
MT=mt.exe
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
# VS2005 on x86 restricts the use of certain libc functions without this
|
||||
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!if "$(COMPILER_NAME)" == "VS2008"
|
||||
@ -185,10 +181,6 @@ LINK_FLAGS = /manifest $(LINK_FLAGS)
|
||||
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||
# as resources inside build artifacts.
|
||||
MT=mt.exe
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
# VS2005 on x86 restricts the use of certain libc functions without this
|
||||
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# Compile for space above time.
|
||||
|
@ -48,6 +48,8 @@ MakeDepsSources=\
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatform.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC6.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC7.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC8.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC9.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\Util.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\BuildConfig.java \
|
||||
$(WorkSpace)\src\share\tools\MakeDeps\ArgsParser.java
|
||||
@ -121,7 +123,7 @@ MakeDepsIDEOptions=\
|
||||
-additionalFile includeDB_gc_shared \
|
||||
-additionalFile includeDB_gc_serial \
|
||||
-additionalGeneratedFile $(HOTSPOTBUILDSPACE)\%f\%b vm.def \
|
||||
-prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh" \
|
||||
-prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
|
||||
$(MakeDepsIncludesPRIVATE)
|
||||
|
||||
# Add in build-specific options
|
||||
|
@ -42,10 +42,23 @@ COMPILE_RMIC=rmic
|
||||
BOOT_JAVA_HOME=
|
||||
!endif
|
||||
|
||||
ProjectFile=vm.vcproj
|
||||
|
||||
!if "$(MSC_VER)" == "1200"
|
||||
|
||||
VcVersion=VC6
|
||||
ProjectFile=vm.dsp
|
||||
|
||||
!elseif "$(MSC_VER)" == "1400"
|
||||
|
||||
VcVersion=VC8
|
||||
|
||||
!elseif "$(MSC_VER)" == "1500"
|
||||
|
||||
VcVersion=VC9
|
||||
|
||||
!else
|
||||
|
||||
VcVersion=VC7
|
||||
ProjectFile=vm.vcproj
|
||||
|
||||
!endif
|
||||
|
@ -89,9 +89,11 @@ checkAndBuildSA:: $(SAWINDBG)
|
||||
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 $(GX_OPTION) /Od /D "WIN32" /D "WIN64" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
!elseif "$(BUILDARCH)" == "amd64"
|
||||
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 $(GX_OPTION) /Od /D "WIN32" /D "WIN64" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
!if "$(COMPILER_NAME)" == "VS2005"
|
||||
# On amd64, VS2005 compiler requires bufferoverflowU.lib on the link command line,
|
||||
# otherwise we get missing __security_check_cookie externals at link time.
|
||||
SA_LINK_FLAGS = bufferoverflowU.lib
|
||||
!endif
|
||||
!else
|
||||
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
!endif
|
||||
|
@ -27,9 +27,9 @@
|
||||
all: checkCL checkLink
|
||||
|
||||
checkCL:
|
||||
@ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" \
|
||||
@ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" \
|
||||
echo *** WARNING *** unrecognized cl.exe version $(MSC_VER) ($(RAW_MSC_VER)). Use FORCE_MSC_VER to override automatic detection.
|
||||
|
||||
checkLink:
|
||||
@ if "$(LINK_VER)" NEQ "710" if "$(LINK_VER)" NEQ "800" \
|
||||
@ if "$(LINK_VER)" NEQ "710" if "$(LINK_VER)" NEQ "800" if "$(LINK_VER)" NEQ "900" \
|
||||
echo *** WARNING *** unrecognized link.exe version $(LINK_VER) ($(RAW_LINK_VER)). Use FORCE_LINK_VER to override automatic detection.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -2615,6 +2615,420 @@ void MacroAssembler::cas_under_lock(Register top_ptr_reg, Register top_reg, Regi
|
||||
}
|
||||
}
|
||||
|
||||
RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
|
||||
Register tmp,
|
||||
int offset) {
|
||||
intptr_t value = *delayed_value_addr;
|
||||
if (value != 0)
|
||||
return RegisterOrConstant(value + offset);
|
||||
|
||||
// load indirectly to solve generation ordering problem
|
||||
Address a(tmp, (address) delayed_value_addr);
|
||||
load_ptr_contents(a, tmp);
|
||||
|
||||
#ifdef ASSERT
|
||||
tst(tmp);
|
||||
breakpoint_trap(zero, xcc);
|
||||
#endif
|
||||
|
||||
if (offset != 0)
|
||||
add(tmp, offset, tmp);
|
||||
|
||||
return RegisterOrConstant(tmp);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
|
||||
assert(dest.register_or_noreg() != G0, "lost side effect");
|
||||
if ((src.is_constant() && src.as_constant() == 0) ||
|
||||
(src.is_register() && src.as_register() == G0)) {
|
||||
// do nothing
|
||||
} else if (dest.is_register()) {
|
||||
add(dest.as_register(), ensure_rs2(src, temp), dest.as_register());
|
||||
} else if (src.is_constant()) {
|
||||
intptr_t res = dest.as_constant() + src.as_constant();
|
||||
dest = RegisterOrConstant(res); // side effect seen by caller
|
||||
} else {
|
||||
assert(temp != noreg, "cannot handle constant += register");
|
||||
add(src.as_register(), ensure_rs2(dest, temp), temp);
|
||||
dest = RegisterOrConstant(temp); // side effect seen by caller
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
|
||||
assert(dest.register_or_noreg() != G0, "lost side effect");
|
||||
if (!is_simm13(src.constant_or_zero()))
|
||||
src = (src.as_constant() & 0xFF);
|
||||
if ((src.is_constant() && src.as_constant() == 0) ||
|
||||
(src.is_register() && src.as_register() == G0)) {
|
||||
// do nothing
|
||||
} else if (dest.is_register()) {
|
||||
sll_ptr(dest.as_register(), src, dest.as_register());
|
||||
} else if (src.is_constant()) {
|
||||
intptr_t res = dest.as_constant() << src.as_constant();
|
||||
dest = RegisterOrConstant(res); // side effect seen by caller
|
||||
} else {
|
||||
assert(temp != noreg, "cannot handle constant <<= register");
|
||||
set(dest.as_constant(), temp);
|
||||
sll_ptr(temp, src, temp);
|
||||
dest = RegisterOrConstant(temp); // side effect seen by caller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Look up the method for a megamorphic invokeinterface call.
|
||||
// The target method is determined by <intf_klass, itable_index>.
|
||||
// The receiver klass is in recv_klass.
|
||||
// On success, the result will be in method_result, and execution falls through.
|
||||
// On failure, execution transfers to the given label.
|
||||
void MacroAssembler::lookup_interface_method(Register recv_klass,
|
||||
Register intf_klass,
|
||||
RegisterOrConstant itable_index,
|
||||
Register method_result,
|
||||
Register scan_temp,
|
||||
Register sethi_temp,
|
||||
Label& L_no_such_interface) {
|
||||
assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
|
||||
assert(itable_index.is_constant() || itable_index.as_register() == method_result,
|
||||
"caller must use same register for non-constant itable index as for method");
|
||||
|
||||
// Compute start of first itableOffsetEntry (which is at the end of the vtable)
|
||||
int vtable_base = instanceKlass::vtable_start_offset() * wordSize;
|
||||
int scan_step = itableOffsetEntry::size() * wordSize;
|
||||
int vte_size = vtableEntry::size() * wordSize;
|
||||
|
||||
lduw(recv_klass, instanceKlass::vtable_length_offset() * wordSize, scan_temp);
|
||||
// %%% We should store the aligned, prescaled offset in the klassoop.
|
||||
// Then the next several instructions would fold away.
|
||||
|
||||
int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0);
|
||||
int itb_offset = vtable_base;
|
||||
if (round_to_unit != 0) {
|
||||
// hoist first instruction of round_to(scan_temp, BytesPerLong):
|
||||
itb_offset += round_to_unit - wordSize;
|
||||
}
|
||||
int itb_scale = exact_log2(vtableEntry::size() * wordSize);
|
||||
sll(scan_temp, itb_scale, scan_temp);
|
||||
add(scan_temp, itb_offset, scan_temp);
|
||||
if (round_to_unit != 0) {
|
||||
// Round up to align_object_offset boundary
|
||||
// see code for instanceKlass::start_of_itable!
|
||||
// Was: round_to(scan_temp, BytesPerLong);
|
||||
// Hoisted: add(scan_temp, BytesPerLong-1, scan_temp);
|
||||
and3(scan_temp, -round_to_unit, scan_temp);
|
||||
}
|
||||
add(recv_klass, scan_temp, scan_temp);
|
||||
|
||||
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
|
||||
RegisterOrConstant itable_offset = itable_index;
|
||||
regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
|
||||
regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
|
||||
add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass);
|
||||
|
||||
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
|
||||
// if (scan->interface() == intf) {
|
||||
// result = (klass + scan->offset() + itable_index);
|
||||
// }
|
||||
// }
|
||||
Label search, found_method;
|
||||
|
||||
for (int peel = 1; peel >= 0; peel--) {
|
||||
// %%%% Could load both offset and interface in one ldx, if they were
|
||||
// in the opposite order. This would save a load.
|
||||
ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result);
|
||||
|
||||
// Check that this entry is non-null. A null entry means that
|
||||
// the receiver class doesn't implement the interface, and wasn't the
|
||||
// same as when the caller was compiled.
|
||||
bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface);
|
||||
delayed()->cmp(method_result, intf_klass);
|
||||
|
||||
if (peel) {
|
||||
brx(Assembler::equal, false, Assembler::pt, found_method);
|
||||
} else {
|
||||
brx(Assembler::notEqual, false, Assembler::pn, search);
|
||||
// (invert the test to fall through to found_method...)
|
||||
}
|
||||
delayed()->add(scan_temp, scan_step, scan_temp);
|
||||
|
||||
if (!peel) break;
|
||||
|
||||
bind(search);
|
||||
}
|
||||
|
||||
bind(found_method);
|
||||
|
||||
// Got a hit.
|
||||
int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
|
||||
// scan_temp[-scan_step] points to the vtable offset we need
|
||||
ito_offset -= scan_step;
|
||||
lduw(scan_temp, ito_offset, scan_temp);
|
||||
ld_ptr(recv_klass, scan_temp, method_result);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::check_klass_subtype(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Label& L_success) {
|
||||
Label L_failure, L_pop_to_failure;
|
||||
check_klass_subtype_fast_path(sub_klass, super_klass,
|
||||
temp_reg, temp2_reg,
|
||||
&L_success, &L_failure, NULL);
|
||||
Register sub_2 = sub_klass;
|
||||
Register sup_2 = super_klass;
|
||||
if (!sub_2->is_global()) sub_2 = L0;
|
||||
if (!sup_2->is_global()) sup_2 = L1;
|
||||
|
||||
save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
|
||||
check_klass_subtype_slow_path(sub_2, sup_2,
|
||||
L2, L3, L4, L5,
|
||||
NULL, &L_pop_to_failure);
|
||||
|
||||
// on success:
|
||||
restore();
|
||||
ba(false, L_success);
|
||||
delayed()->nop();
|
||||
|
||||
// on failure:
|
||||
bind(L_pop_to_failure);
|
||||
restore();
|
||||
bind(L_failure);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure,
|
||||
Label* L_slow_path,
|
||||
RegisterOrConstant super_check_offset,
|
||||
Register instanceof_hack) {
|
||||
int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_super_cache_offset_in_bytes());
|
||||
int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::super_check_offset_offset_in_bytes());
|
||||
|
||||
bool must_load_sco = (super_check_offset.constant_or_zero() == -1);
|
||||
bool need_slow_path = (must_load_sco ||
|
||||
super_check_offset.constant_or_zero() == sco_offset);
|
||||
|
||||
assert_different_registers(sub_klass, super_klass, temp_reg);
|
||||
if (super_check_offset.is_register()) {
|
||||
assert_different_registers(sub_klass, super_klass,
|
||||
super_check_offset.as_register());
|
||||
} else if (must_load_sco) {
|
||||
assert(temp2_reg != noreg, "supply either a temp or a register offset");
|
||||
}
|
||||
|
||||
Label L_fallthrough;
|
||||
int label_nulls = 0;
|
||||
if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
|
||||
if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
|
||||
if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; }
|
||||
assert(label_nulls <= 1 || instanceof_hack != noreg ||
|
||||
(L_slow_path == &L_fallthrough && label_nulls <= 2 && !need_slow_path),
|
||||
"at most one NULL in the batch, usually");
|
||||
|
||||
// Support for the instanceof hack, which uses delay slots to
|
||||
// set a destination register to zero or one.
|
||||
bool do_bool_sets = (instanceof_hack != noreg);
|
||||
#define BOOL_SET(bool_value) \
|
||||
if (do_bool_sets && bool_value >= 0) \
|
||||
set(bool_value, instanceof_hack)
|
||||
#define DELAYED_BOOL_SET(bool_value) \
|
||||
if (do_bool_sets && bool_value >= 0) \
|
||||
delayed()->set(bool_value, instanceof_hack); \
|
||||
else delayed()->nop()
|
||||
// Hacked ba(), which may only be used just before L_fallthrough.
|
||||
#define FINAL_JUMP(label, bool_value) \
|
||||
if (&(label) == &L_fallthrough) { \
|
||||
BOOL_SET(bool_value); \
|
||||
} else { \
|
||||
ba((do_bool_sets && bool_value >= 0), label); \
|
||||
DELAYED_BOOL_SET(bool_value); \
|
||||
}
|
||||
|
||||
// If the pointers are equal, we are done (e.g., String[] elements).
|
||||
// This self-check enables sharing of secondary supertype arrays among
|
||||
// non-primary types such as array-of-interface. Otherwise, each such
|
||||
// type would need its own customized SSA.
|
||||
// We move this check to the front of the fast path because many
|
||||
// type checks are in fact trivially successful in this manner,
|
||||
// so we get a nicely predicted branch right at the start of the check.
|
||||
cmp(super_klass, sub_klass);
|
||||
brx(Assembler::equal, do_bool_sets, Assembler::pn, *L_success);
|
||||
DELAYED_BOOL_SET(1);
|
||||
|
||||
// Check the supertype display:
|
||||
if (must_load_sco) {
|
||||
// The super check offset is always positive...
|
||||
lduw(super_klass, sco_offset, temp2_reg);
|
||||
super_check_offset = RegisterOrConstant(temp2_reg);
|
||||
}
|
||||
ld_ptr(sub_klass, super_check_offset, temp_reg);
|
||||
cmp(super_klass, temp_reg);
|
||||
|
||||
// This check has worked decisively for primary supers.
|
||||
// Secondary supers are sought in the super_cache ('super_cache_addr').
|
||||
// (Secondary supers are interfaces and very deeply nested subtypes.)
|
||||
// This works in the same check above because of a tricky aliasing
|
||||
// between the super_cache and the primary super display elements.
|
||||
// (The 'super_check_addr' can address either, as the case requires.)
|
||||
// Note that the cache is updated below if it does not help us find
|
||||
// what we need immediately.
|
||||
// So if it was a primary super, we can just fail immediately.
|
||||
// Otherwise, it's the slow path for us (no success at this point).
|
||||
|
||||
if (super_check_offset.is_register()) {
|
||||
brx(Assembler::equal, do_bool_sets, Assembler::pn, *L_success);
|
||||
delayed(); if (do_bool_sets) BOOL_SET(1);
|
||||
// if !do_bool_sets, sneak the next cmp into the delay slot:
|
||||
cmp(super_check_offset.as_register(), sc_offset);
|
||||
|
||||
if (L_failure == &L_fallthrough) {
|
||||
brx(Assembler::equal, do_bool_sets, Assembler::pt, *L_slow_path);
|
||||
delayed()->nop();
|
||||
BOOL_SET(0); // fallthrough on failure
|
||||
} else {
|
||||
brx(Assembler::notEqual, do_bool_sets, Assembler::pn, *L_failure);
|
||||
DELAYED_BOOL_SET(0);
|
||||
FINAL_JUMP(*L_slow_path, -1); // -1 => vanilla delay slot
|
||||
}
|
||||
} else if (super_check_offset.as_constant() == sc_offset) {
|
||||
// Need a slow path; fast failure is impossible.
|
||||
if (L_slow_path == &L_fallthrough) {
|
||||
brx(Assembler::equal, do_bool_sets, Assembler::pt, *L_success);
|
||||
DELAYED_BOOL_SET(1);
|
||||
} else {
|
||||
brx(Assembler::notEqual, false, Assembler::pn, *L_slow_path);
|
||||
delayed()->nop();
|
||||
FINAL_JUMP(*L_success, 1);
|
||||
}
|
||||
} else {
|
||||
// No slow path; it's a fast decision.
|
||||
if (L_failure == &L_fallthrough) {
|
||||
brx(Assembler::equal, do_bool_sets, Assembler::pt, *L_success);
|
||||
DELAYED_BOOL_SET(1);
|
||||
BOOL_SET(0);
|
||||
} else {
|
||||
brx(Assembler::notEqual, do_bool_sets, Assembler::pn, *L_failure);
|
||||
DELAYED_BOOL_SET(0);
|
||||
FINAL_JUMP(*L_success, 1);
|
||||
}
|
||||
}
|
||||
|
||||
bind(L_fallthrough);
|
||||
|
||||
#undef final_jump
|
||||
#undef bool_set
|
||||
#undef DELAYED_BOOL_SET
|
||||
#undef final_jump
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register count_temp,
|
||||
Register scan_temp,
|
||||
Register scratch_reg,
|
||||
Register coop_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure) {
|
||||
assert_different_registers(sub_klass, super_klass,
|
||||
count_temp, scan_temp, scratch_reg, coop_reg);
|
||||
|
||||
Label L_fallthrough, L_loop;
|
||||
int label_nulls = 0;
|
||||
if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
|
||||
if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
|
||||
assert(label_nulls <= 1, "at most one NULL in the batch");
|
||||
|
||||
// a couple of useful fields in sub_klass:
|
||||
int ss_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_supers_offset_in_bytes());
|
||||
int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_super_cache_offset_in_bytes());
|
||||
|
||||
// Do a linear scan of the secondary super-klass chain.
|
||||
// This code is rarely used, so simplicity is a virtue here.
|
||||
|
||||
#ifndef PRODUCT
|
||||
int* pst_counter = &SharedRuntime::_partial_subtype_ctr;
|
||||
inc_counter((address) pst_counter, count_temp, scan_temp);
|
||||
#endif
|
||||
|
||||
// We will consult the secondary-super array.
|
||||
ld_ptr(sub_klass, ss_offset, scan_temp);
|
||||
|
||||
// Compress superclass if necessary.
|
||||
Register search_key = super_klass;
|
||||
bool decode_super_klass = false;
|
||||
if (UseCompressedOops) {
|
||||
if (coop_reg != noreg) {
|
||||
encode_heap_oop_not_null(super_klass, coop_reg);
|
||||
search_key = coop_reg;
|
||||
} else {
|
||||
encode_heap_oop_not_null(super_klass);
|
||||
decode_super_klass = true; // scarce temps!
|
||||
}
|
||||
// The superclass is never null; it would be a basic system error if a null
|
||||
// pointer were to sneak in here. Note that we have already loaded the
|
||||
// Klass::super_check_offset from the super_klass in the fast path,
|
||||
// so if there is a null in that register, we are already in the afterlife.
|
||||
}
|
||||
|
||||
// Load the array length. (Positive movl does right thing on LP64.)
|
||||
lduw(scan_temp, arrayOopDesc::length_offset_in_bytes(), count_temp);
|
||||
|
||||
// Check for empty secondary super list
|
||||
tst(count_temp);
|
||||
|
||||
// Top of search loop
|
||||
bind(L_loop);
|
||||
br(Assembler::equal, false, Assembler::pn, *L_failure);
|
||||
delayed()->add(scan_temp, heapOopSize, scan_temp);
|
||||
assert(heapOopSize != 0, "heapOopSize should be initialized");
|
||||
|
||||
// Skip the array header in all array accesses.
|
||||
int elem_offset = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
|
||||
elem_offset -= heapOopSize; // the scan pointer was pre-incremented also
|
||||
|
||||
// Load next super to check
|
||||
if (UseCompressedOops) {
|
||||
// Don't use load_heap_oop; we don't want to decode the element.
|
||||
lduw( scan_temp, elem_offset, scratch_reg );
|
||||
} else {
|
||||
ld_ptr( scan_temp, elem_offset, scratch_reg );
|
||||
}
|
||||
|
||||
// Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list
|
||||
cmp(scratch_reg, search_key);
|
||||
|
||||
// A miss means we are NOT a subtype and need to keep looping
|
||||
brx(Assembler::notEqual, false, Assembler::pn, L_loop);
|
||||
delayed()->deccc(count_temp); // decrement trip counter in delay slot
|
||||
|
||||
// Falling out the bottom means we found a hit; we ARE a subtype
|
||||
if (decode_super_klass) decode_heap_oop(super_klass);
|
||||
|
||||
// Success. Cache the super we found and proceed in triumph.
|
||||
st_ptr(super_klass, sub_klass, sc_offset);
|
||||
|
||||
if (L_success != &L_fallthrough) {
|
||||
ba(false, *L_success);
|
||||
delayed()->nop();
|
||||
}
|
||||
|
||||
bind(L_fallthrough);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
|
||||
Register temp_reg,
|
||||
Label& done, Label* slow_case,
|
||||
@ -3820,7 +4234,6 @@ void MacroAssembler::g1_write_barrier_pre(Register obj, Register index, int offs
|
||||
static jint num_ct_writes = 0;
|
||||
static jint num_ct_writes_filtered_in_hr = 0;
|
||||
static jint num_ct_writes_filtered_null = 0;
|
||||
static jint num_ct_writes_filtered_pop = 0;
|
||||
static G1CollectedHeap* g1 = NULL;
|
||||
|
||||
static Thread* count_ct_writes(void* filter_val, void* new_val) {
|
||||
@ -3833,25 +4246,19 @@ static Thread* count_ct_writes(void* filter_val, void* new_val) {
|
||||
if (g1 == NULL) {
|
||||
g1 = G1CollectedHeap::heap();
|
||||
}
|
||||
if ((HeapWord*)new_val < g1->popular_object_boundary()) {
|
||||
Atomic::inc(&num_ct_writes_filtered_pop);
|
||||
}
|
||||
}
|
||||
if ((num_ct_writes % 1000000) == 0) {
|
||||
jint num_ct_writes_filtered =
|
||||
num_ct_writes_filtered_in_hr +
|
||||
num_ct_writes_filtered_null +
|
||||
num_ct_writes_filtered_pop;
|
||||
num_ct_writes_filtered_null;
|
||||
|
||||
tty->print_cr("%d potential CT writes: %5.2f%% filtered\n"
|
||||
" (%5.2f%% intra-HR, %5.2f%% null, %5.2f%% popular).",
|
||||
" (%5.2f%% intra-HR, %5.2f%% null).",
|
||||
num_ct_writes,
|
||||
100.0*(float)num_ct_writes_filtered/(float)num_ct_writes,
|
||||
100.0*(float)num_ct_writes_filtered_in_hr/
|
||||
(float)num_ct_writes,
|
||||
100.0*(float)num_ct_writes_filtered_null/
|
||||
(float)num_ct_writes,
|
||||
100.0*(float)num_ct_writes_filtered_pop/
|
||||
(float)num_ct_writes);
|
||||
}
|
||||
return Thread::current();
|
||||
@ -4057,6 +4464,24 @@ void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_v
|
||||
card_table_write(bs->byte_map_base, tmp, store_addr);
|
||||
}
|
||||
|
||||
// Loading values by size and signed-ness
|
||||
void MacroAssembler::load_sized_value(Register s1, RegisterOrConstant s2, Register d,
|
||||
int size_in_bytes, bool is_signed) {
|
||||
switch (size_in_bytes ^ (is_signed ? -1 : 0)) {
|
||||
case ~8: // fall through:
|
||||
case 8: ld_long( s1, s2, d ); break;
|
||||
case ~4: ldsw( s1, s2, d ); break;
|
||||
case 4: lduw( s1, s2, d ); break;
|
||||
case ~2: ldsh( s1, s2, d ); break;
|
||||
case 2: lduh( s1, s2, d ); break;
|
||||
case ~1: ldsb( s1, s2, d ); break;
|
||||
case 1: ldub( s1, s2, d ); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MacroAssembler::load_klass(Register src_oop, Register klass) {
|
||||
// The number of bytes in this code is used by
|
||||
// MachCallDynamicJavaNode::ret_addr_offset()
|
||||
@ -4146,7 +4571,13 @@ void MacroAssembler::store_heap_oop(Register d, const Address& a, int offset) {
|
||||
|
||||
void MacroAssembler::encode_heap_oop(Register src, Register dst) {
|
||||
assert (UseCompressedOops, "must be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
verify_oop(src);
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
srlx(src, LogMinObjAlignmentInBytes, dst);
|
||||
return;
|
||||
}
|
||||
Label done;
|
||||
if (src == dst) {
|
||||
// optimize for frequent case src == dst
|
||||
@ -4168,26 +4599,39 @@ void MacroAssembler::encode_heap_oop(Register src, Register dst) {
|
||||
|
||||
void MacroAssembler::encode_heap_oop_not_null(Register r) {
|
||||
assert (UseCompressedOops, "must be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
verify_oop(r);
|
||||
if (Universe::narrow_oop_base() != NULL)
|
||||
sub(r, G6_heapbase, r);
|
||||
srlx(r, LogMinObjAlignmentInBytes, r);
|
||||
}
|
||||
|
||||
void MacroAssembler::encode_heap_oop_not_null(Register src, Register dst) {
|
||||
assert (UseCompressedOops, "must be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
verify_oop(src);
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
srlx(src, LogMinObjAlignmentInBytes, dst);
|
||||
} else {
|
||||
sub(src, G6_heapbase, dst);
|
||||
srlx(dst, LogMinObjAlignmentInBytes, dst);
|
||||
}
|
||||
}
|
||||
|
||||
// Same algorithm as oops.inline.hpp decode_heap_oop.
|
||||
void MacroAssembler::decode_heap_oop(Register src, Register dst) {
|
||||
assert (UseCompressedOops, "must be compressed");
|
||||
Label done;
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
sllx(src, LogMinObjAlignmentInBytes, dst);
|
||||
if (Universe::narrow_oop_base() != NULL) {
|
||||
Label done;
|
||||
bpr(rc_nz, true, Assembler::pt, dst, done);
|
||||
delayed() -> add(dst, G6_heapbase, dst); // annuled if not taken
|
||||
bind(done);
|
||||
}
|
||||
verify_oop(dst);
|
||||
}
|
||||
|
||||
@ -4196,7 +4640,10 @@ void MacroAssembler::decode_heap_oop_not_null(Register r) {
|
||||
// pd_code_size_limit.
|
||||
// Also do not verify_oop as this is called by verify_oop.
|
||||
assert (UseCompressedOops, "must be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
sllx(r, LogMinObjAlignmentInBytes, r);
|
||||
if (Universe::narrow_oop_base() != NULL)
|
||||
add(r, G6_heapbase, r);
|
||||
}
|
||||
|
||||
@ -4205,14 +4652,17 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
|
||||
// pd_code_size_limit.
|
||||
// Also do not verify_oop as this is called by verify_oop.
|
||||
assert (UseCompressedOops, "must be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
sllx(src, LogMinObjAlignmentInBytes, dst);
|
||||
if (Universe::narrow_oop_base() != NULL)
|
||||
add(dst, G6_heapbase, dst);
|
||||
}
|
||||
|
||||
void MacroAssembler::reinit_heapbase() {
|
||||
if (UseCompressedOops) {
|
||||
// call indirectly to solve generation ordering problem
|
||||
Address base(G6_heapbase, (address)Universe::heap_base_addr());
|
||||
Address base(G6_heapbase, (address)Universe::narrow_oop_base_addr());
|
||||
load_ptr_contents(base, G6_heapbase);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -384,6 +384,12 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
inline bool is_simm13(int offset = 0); // check disp+offset for overflow
|
||||
|
||||
Address plus_disp(int disp) const { // bump disp by a small amount
|
||||
Address a = (*this);
|
||||
a._disp += disp;
|
||||
return a;
|
||||
}
|
||||
|
||||
Address split_disp() const { // deal with disp overflow
|
||||
Address a = (*this);
|
||||
int hi_disp = _disp & ~0x3ff;
|
||||
@ -1082,6 +1088,7 @@ public:
|
||||
inline void add( Register s1, Register s2, Register d );
|
||||
inline void add( Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none);
|
||||
inline void add( Register s1, int simm13a, Register d, RelocationHolder const& rspec);
|
||||
inline void add( Register s1, RegisterOrConstant s2, Register d, int offset = 0);
|
||||
inline void add( const Address& a, Register d, int offset = 0);
|
||||
|
||||
void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
|
||||
@ -1298,6 +1305,16 @@ public:
|
||||
inline void ld( const Address& a, Register d, int offset = 0 );
|
||||
inline void ldd( const Address& a, Register d, int offset = 0 );
|
||||
|
||||
inline void ldub( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ldsb( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void lduh( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ldsh( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void lduw( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ldsw( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ldx( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ld( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ldd( Register s1, RegisterOrConstant s2, Register d );
|
||||
|
||||
// pp 177
|
||||
|
||||
void ldsba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
|
||||
@ -1518,6 +1535,13 @@ public:
|
||||
inline void st( Register d, const Address& a, int offset = 0 );
|
||||
inline void std( Register d, const Address& a, int offset = 0 );
|
||||
|
||||
inline void stb( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void sth( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void stw( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void stx( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void std( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void st( Register d, Register s1, RegisterOrConstant s2 );
|
||||
|
||||
// pp 177
|
||||
|
||||
void stba( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
|
||||
@ -1835,6 +1859,7 @@ class MacroAssembler: public Assembler {
|
||||
// Functions for isolating 64 bit shifts for LP64
|
||||
inline void sll_ptr( Register s1, Register s2, Register d );
|
||||
inline void sll_ptr( Register s1, int imm6a, Register d );
|
||||
inline void sll_ptr( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void srl_ptr( Register s1, Register s2, Register d );
|
||||
inline void srl_ptr( Register s1, int imm6a, Register d );
|
||||
|
||||
@ -1940,20 +1965,47 @@ class MacroAssembler: public Assembler {
|
||||
// st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's
|
||||
inline void ld_ptr( Register s1, Register s2, Register d );
|
||||
inline void ld_ptr( Register s1, int simm13a, Register d);
|
||||
inline void ld_ptr( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ld_ptr( const Address& a, Register d, int offset = 0 );
|
||||
inline void st_ptr( Register d, Register s1, Register s2 );
|
||||
inline void st_ptr( Register d, Register s1, int simm13a);
|
||||
inline void st_ptr( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void st_ptr( Register d, const Address& a, int offset = 0 );
|
||||
|
||||
// ld_long will perform ld for 32 bit VM's and ldx for 64 bit VM's
|
||||
// st_long will perform st for 32 bit VM's and stx for 64 bit VM's
|
||||
inline void ld_long( Register s1, Register s2, Register d );
|
||||
inline void ld_long( Register s1, int simm13a, Register d );
|
||||
inline void ld_long( Register s1, RegisterOrConstant s2, Register d );
|
||||
inline void ld_long( const Address& a, Register d, int offset = 0 );
|
||||
inline void st_long( Register d, Register s1, Register s2 );
|
||||
inline void st_long( Register d, Register s1, int simm13a );
|
||||
inline void st_long( Register d, Register s1, RegisterOrConstant s2 );
|
||||
inline void st_long( Register d, const Address& a, int offset = 0 );
|
||||
|
||||
// Loading values by size and signed-ness
|
||||
void load_sized_value(Register s1, RegisterOrConstant s2, Register d,
|
||||
int size_in_bytes, bool is_signed);
|
||||
|
||||
// Helpers for address formation.
|
||||
// They update the dest in place, whether it is a register or constant.
|
||||
// They emit no code at all if src is a constant zero.
|
||||
// If dest is a constant and src is a register, the temp argument
|
||||
// is required, and becomes the result.
|
||||
// If dest is a register and src is a non-simm13 constant,
|
||||
// the temp argument is required, and is used to materialize the constant.
|
||||
void regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src,
|
||||
Register temp = noreg );
|
||||
void regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src,
|
||||
Register temp = noreg );
|
||||
RegisterOrConstant ensure_rs2(RegisterOrConstant rs2, Register sethi_temp) {
|
||||
guarantee(sethi_temp != noreg, "constant offset overflow");
|
||||
if (is_simm13(rs2.constant_or_zero()))
|
||||
return rs2; // register or short constant
|
||||
set(rs2.as_constant(), sethi_temp);
|
||||
return sethi_temp;
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
|
||||
public:
|
||||
@ -2267,6 +2319,54 @@ class MacroAssembler: public Assembler {
|
||||
);
|
||||
void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
|
||||
|
||||
// interface method calling
|
||||
void lookup_interface_method(Register recv_klass,
|
||||
Register intf_klass,
|
||||
RegisterOrConstant itable_index,
|
||||
Register method_result,
|
||||
Register temp_reg, Register temp2_reg,
|
||||
Label& no_such_interface);
|
||||
|
||||
// Test sub_klass against super_klass, with fast and slow paths.
|
||||
|
||||
// The fast path produces a tri-state answer: yes / no / maybe-slow.
|
||||
// One of the three labels can be NULL, meaning take the fall-through.
|
||||
// If super_check_offset is -1, the value is loaded up from super_klass.
|
||||
// No registers are killed, except temp_reg and temp2_reg.
|
||||
// If super_check_offset is not -1, temp2_reg is not used and can be noreg.
|
||||
void check_klass_subtype_fast_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure,
|
||||
Label* L_slow_path,
|
||||
RegisterOrConstant super_check_offset = RegisterOrConstant(-1),
|
||||
Register instanceof_hack = noreg);
|
||||
|
||||
// The rest of the type check; must be wired to a corresponding fast path.
|
||||
// It does not repeat the fast path logic, so don't use it standalone.
|
||||
// The temp_reg can be noreg, if no temps are available.
|
||||
// It can also be sub_klass or super_klass, meaning it's OK to kill that one.
|
||||
// Updates the sub's secondary super cache as necessary.
|
||||
void check_klass_subtype_slow_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Register temp3_reg,
|
||||
Register temp4_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure);
|
||||
|
||||
// Simplified, combined version, good for typical uses.
|
||||
// Falls through on failure.
|
||||
void check_klass_subtype(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Label& L_success);
|
||||
|
||||
|
||||
// Stack overflow checking
|
||||
|
||||
// Note: this clobbers G3_scratch
|
||||
@ -2281,6 +2381,8 @@ class MacroAssembler: public Assembler {
|
||||
// stack overflow + shadow pages. Clobbers tsp and scratch registers.
|
||||
void bang_stack_size(Register Rsize, Register Rtsp, Register Rscratch);
|
||||
|
||||
virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset);
|
||||
|
||||
void verify_tlab();
|
||||
|
||||
Condition negate_condition(Condition cond);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -143,6 +143,49 @@ inline void Assembler::ld( Register s1, Register s2, Register d) { lduw( s1, s2
|
||||
inline void Assembler::ld( Register s1, int simm13a, Register d) { lduw( s1, simm13a, d); }
|
||||
#endif
|
||||
|
||||
inline void Assembler::ldub( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldsb(s1, s2.as_register(), d);
|
||||
else ldsb(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::ldsb( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldsb(s1, s2.as_register(), d);
|
||||
else ldsb(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::lduh( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldsh(s1, s2.as_register(), d);
|
||||
else ldsh(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::ldsh( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldsh(s1, s2.as_register(), d);
|
||||
else ldsh(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::lduw( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldsw(s1, s2.as_register(), d);
|
||||
else ldsw(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::ldsw( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldsw(s1, s2.as_register(), d);
|
||||
else ldsw(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::ldx( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldx(s1, s2.as_register(), d);
|
||||
else ldx(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::ld( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ld(s1, s2.as_register(), d);
|
||||
else ld(s1, s2.as_constant(), d);
|
||||
}
|
||||
inline void Assembler::ldd( Register s1, RegisterOrConstant s2, Register d) {
|
||||
if (s2.is_register()) ldd(s1, s2.as_register(), d);
|
||||
else ldd(s1, s2.as_constant(), d);
|
||||
}
|
||||
|
||||
// form effective addresses this way:
|
||||
inline void Assembler::add( Register s1, RegisterOrConstant s2, Register d, int offset) {
|
||||
if (s2.is_register()) add(s1, s2.as_register(), d);
|
||||
else { add(s1, s2.as_constant() + offset, d); offset = 0; }
|
||||
if (offset != 0) add(d, offset, d);
|
||||
}
|
||||
|
||||
inline void Assembler::ld( const Address& a, Register d, int offset ) { relocate(a.rspec(offset)); ld( a.base(), a.disp() + offset, d ); }
|
||||
inline void Assembler::ldsb( const Address& a, Register d, int offset ) { relocate(a.rspec(offset)); ldsb( a.base(), a.disp() + offset, d ); }
|
||||
@ -200,6 +243,27 @@ inline void Assembler::std( Register d, Register s1, int simm13a) { v9_dep(); a
|
||||
inline void Assembler::st( Register d, Register s1, Register s2) { stw(d, s1, s2); }
|
||||
inline void Assembler::st( Register d, Register s1, int simm13a) { stw(d, s1, simm13a); }
|
||||
|
||||
inline void Assembler::stb( Register d, Register s1, RegisterOrConstant s2) {
|
||||
if (s2.is_register()) stb(d, s1, s2.as_register());
|
||||
else stb(d, s1, s2.as_constant());
|
||||
}
|
||||
inline void Assembler::sth( Register d, Register s1, RegisterOrConstant s2) {
|
||||
if (s2.is_register()) sth(d, s1, s2.as_register());
|
||||
else sth(d, s1, s2.as_constant());
|
||||
}
|
||||
inline void Assembler::stx( Register d, Register s1, RegisterOrConstant s2) {
|
||||
if (s2.is_register()) stx(d, s1, s2.as_register());
|
||||
else stx(d, s1, s2.as_constant());
|
||||
}
|
||||
inline void Assembler::std( Register d, Register s1, RegisterOrConstant s2) {
|
||||
if (s2.is_register()) std(d, s1, s2.as_register());
|
||||
else std(d, s1, s2.as_constant());
|
||||
}
|
||||
inline void Assembler::st( Register d, Register s1, RegisterOrConstant s2) {
|
||||
if (s2.is_register()) st(d, s1, s2.as_register());
|
||||
else st(d, s1, s2.as_constant());
|
||||
}
|
||||
|
||||
inline void Assembler::stb( Register d, const Address& a, int offset) { relocate(a.rspec(offset)); stb( d, a.base(), a.disp() + offset); }
|
||||
inline void Assembler::sth( Register d, const Address& a, int offset) { relocate(a.rspec(offset)); sth( d, a.base(), a.disp() + offset); }
|
||||
inline void Assembler::stw( Register d, const Address& a, int offset) { relocate(a.rspec(offset)); stw( d, a.base(), a.disp() + offset); }
|
||||
@ -244,6 +308,14 @@ inline void MacroAssembler::ld_ptr( Register s1, int simm13a, Register d ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::ld_ptr( Register s1, RegisterOrConstant s2, Register d ) {
|
||||
#ifdef _LP64
|
||||
Assembler::ldx( s1, s2, d);
|
||||
#else
|
||||
Assembler::ld( s1, s2, d);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::ld_ptr( const Address& a, Register d, int offset ) {
|
||||
#ifdef _LP64
|
||||
Assembler::ldx( a, d, offset );
|
||||
@ -268,6 +340,14 @@ inline void MacroAssembler::st_ptr( Register d, Register s1, int simm13a ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::st_ptr( Register d, Register s1, RegisterOrConstant s2 ) {
|
||||
#ifdef _LP64
|
||||
Assembler::stx( d, s1, s2);
|
||||
#else
|
||||
Assembler::st( d, s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::st_ptr( Register d, const Address& a, int offset) {
|
||||
#ifdef _LP64
|
||||
Assembler::stx( d, a, offset);
|
||||
@ -293,6 +373,14 @@ inline void MacroAssembler::ld_long( Register s1, int simm13a, Register d ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::ld_long( Register s1, RegisterOrConstant s2, Register d ) {
|
||||
#ifdef _LP64
|
||||
Assembler::ldx(s1, s2, d);
|
||||
#else
|
||||
Assembler::ldd(s1, s2, d);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::ld_long( const Address& a, Register d, int offset ) {
|
||||
#ifdef _LP64
|
||||
Assembler::ldx(a, d, offset );
|
||||
@ -317,6 +405,14 @@ inline void MacroAssembler::st_long( Register d, Register s1, int simm13a ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::st_long( Register d, Register s1, RegisterOrConstant s2 ) {
|
||||
#ifdef _LP64
|
||||
Assembler::stx(d, s1, s2);
|
||||
#else
|
||||
Assembler::std(d, s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::st_long( Register d, const Address& a, int offset ) {
|
||||
#ifdef _LP64
|
||||
Assembler::stx(d, a, offset);
|
||||
@ -359,6 +455,11 @@ inline void MacroAssembler::srl_ptr( Register s1, int imm6a, Register d ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void MacroAssembler::sll_ptr( Register s1, RegisterOrConstant s2, Register d ) {
|
||||
if (s2.is_register()) sll_ptr(s1, s2.as_register(), d);
|
||||
else sll_ptr(s1, s2.as_constant(), d);
|
||||
}
|
||||
|
||||
// Use the right branch for the platform
|
||||
|
||||
inline void MacroAssembler::br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt ) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 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
|
||||
@ -2393,23 +2393,11 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
|
||||
// get instance klass
|
||||
load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL);
|
||||
// get super_check_offset
|
||||
load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1, T_INT, NULL);
|
||||
// See if we get an immediate positive hit
|
||||
__ ld_ptr(klass_RInfo, Rtmp1, FrameMap::O7_oop_opr->as_register());
|
||||
__ cmp(k_RInfo, O7);
|
||||
__ br(Assembler::equal, false, Assembler::pn, done);
|
||||
__ delayed()->nop();
|
||||
// check for immediate negative hit
|
||||
__ cmp(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ br(Assembler::notEqual, false, Assembler::pn, *stub->entry());
|
||||
__ delayed()->nop();
|
||||
// check for self
|
||||
__ cmp(klass_RInfo, k_RInfo);
|
||||
__ br(Assembler::equal, false, Assembler::pn, done);
|
||||
__ delayed()->nop();
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done, stub->entry(), NULL);
|
||||
|
||||
// assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup");
|
||||
// call out-of-line instance of __ check_klass_subtype_slow_path(...):
|
||||
assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
|
||||
__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
__ cmp(G3, 0);
|
||||
@ -2493,25 +2481,23 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
__ delayed()->nop();
|
||||
__ bind(done);
|
||||
} else {
|
||||
bool need_slow_path = true;
|
||||
if (k->is_loaded()) {
|
||||
load(klass_RInfo, k->super_check_offset(), Rtmp1, T_OBJECT, NULL);
|
||||
|
||||
if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
|
||||
// See if we get an immediate positive hit
|
||||
__ cmp(Rtmp1, k_RInfo );
|
||||
__ br(Assembler::notEqual, false, Assembler::pn, *stub->entry());
|
||||
__ delayed()->nop();
|
||||
if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())
|
||||
need_slow_path = false;
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg,
|
||||
(need_slow_path ? &done : NULL),
|
||||
stub->entry(), NULL,
|
||||
RegisterOrConstant(k->super_check_offset()));
|
||||
} else {
|
||||
// See if we get an immediate positive hit
|
||||
assert_different_registers(Rtmp1, k_RInfo, klass_RInfo);
|
||||
__ cmp(Rtmp1, k_RInfo );
|
||||
__ br(Assembler::equal, false, Assembler::pn, done);
|
||||
// check for self
|
||||
__ delayed()->cmp(klass_RInfo, k_RInfo);
|
||||
__ br(Assembler::equal, false, Assembler::pn, done);
|
||||
__ delayed()->nop();
|
||||
|
||||
// assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup");
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7,
|
||||
&done, stub->entry(), NULL);
|
||||
}
|
||||
if (need_slow_path) {
|
||||
// call out-of-line instance of __ check_klass_subtype_slow_path(...):
|
||||
assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
|
||||
__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
__ cmp(G3, 0);
|
||||
@ -2519,32 +2505,6 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
__ delayed()->nop();
|
||||
}
|
||||
__ bind(done);
|
||||
} else {
|
||||
assert_different_registers(Rtmp1, klass_RInfo, k_RInfo);
|
||||
|
||||
load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1, T_INT, NULL);
|
||||
// See if we get an immediate positive hit
|
||||
load(klass_RInfo, Rtmp1, FrameMap::O7_oop_opr, T_OBJECT);
|
||||
__ cmp(k_RInfo, O7);
|
||||
__ br(Assembler::equal, false, Assembler::pn, done);
|
||||
__ delayed()->nop();
|
||||
// check for immediate negative hit
|
||||
__ cmp(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ br(Assembler::notEqual, false, Assembler::pn, *stub->entry());
|
||||
// check for self
|
||||
__ delayed()->cmp(klass_RInfo, k_RInfo);
|
||||
__ br(Assembler::equal, false, Assembler::pn, done);
|
||||
__ delayed()->nop();
|
||||
|
||||
// assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup");
|
||||
__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
__ cmp(G3, 0);
|
||||
__ br(Assembler::equal, false, Assembler::pn, *stub->entry());
|
||||
__ delayed()->nop();
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
}
|
||||
__ mov(obj, dst);
|
||||
} else if (code == lir_instanceof) {
|
||||
@ -2582,58 +2542,32 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
__ set(0, dst);
|
||||
__ bind(done);
|
||||
} else {
|
||||
bool need_slow_path = true;
|
||||
if (k->is_loaded()) {
|
||||
assert_different_registers(Rtmp1, klass_RInfo, k_RInfo);
|
||||
load(klass_RInfo, k->super_check_offset(), Rtmp1, T_OBJECT, NULL);
|
||||
|
||||
if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
|
||||
// See if we get an immediate positive hit
|
||||
__ cmp(Rtmp1, k_RInfo );
|
||||
__ br(Assembler::equal, true, Assembler::pt, done);
|
||||
__ delayed()->set(1, dst);
|
||||
__ set(0, dst);
|
||||
__ bind(done);
|
||||
} else {
|
||||
// See if we get an immediate positive hit
|
||||
assert_different_registers(Rtmp1, k_RInfo, klass_RInfo);
|
||||
__ cmp(Rtmp1, k_RInfo );
|
||||
__ br(Assembler::equal, true, Assembler::pt, done);
|
||||
__ delayed()->set(1, dst);
|
||||
// check for self
|
||||
__ cmp(klass_RInfo, k_RInfo);
|
||||
__ br(Assembler::equal, true, Assembler::pt, done);
|
||||
__ delayed()->set(1, dst);
|
||||
|
||||
// assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup");
|
||||
__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
__ mov(G3, dst);
|
||||
__ bind(done);
|
||||
}
|
||||
if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())
|
||||
need_slow_path = false;
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, noreg,
|
||||
(need_slow_path ? &done : NULL),
|
||||
(need_slow_path ? &done : NULL), NULL,
|
||||
RegisterOrConstant(k->super_check_offset()),
|
||||
dst);
|
||||
} else {
|
||||
assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers");
|
||||
|
||||
load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), dst, T_INT, NULL);
|
||||
// See if we get an immediate positive hit
|
||||
load(klass_RInfo, dst, FrameMap::O7_oop_opr, T_OBJECT);
|
||||
__ cmp(k_RInfo, O7);
|
||||
__ br(Assembler::equal, true, Assembler::pt, done);
|
||||
__ delayed()->set(1, dst);
|
||||
// check for immediate negative hit
|
||||
__ cmp(dst, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ br(Assembler::notEqual, true, Assembler::pt, done);
|
||||
__ delayed()->set(0, dst);
|
||||
// check for self
|
||||
__ cmp(klass_RInfo, k_RInfo);
|
||||
__ br(Assembler::equal, true, Assembler::pt, done);
|
||||
__ delayed()->set(1, dst);
|
||||
|
||||
// assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup");
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, dst,
|
||||
&done, &done, NULL,
|
||||
RegisterOrConstant(-1),
|
||||
dst);
|
||||
}
|
||||
if (need_slow_path) {
|
||||
// call out-of-line instance of __ check_klass_subtype_slow_path(...):
|
||||
assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
|
||||
__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
__ mov(G3, dst);
|
||||
__ bind(done);
|
||||
}
|
||||
__ bind(done);
|
||||
}
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
@ -714,38 +714,19 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
// sub : G3, argument, destroyed
|
||||
// super: G1, argument, not changed
|
||||
// raddr: O7, blown by call
|
||||
Label loop, miss;
|
||||
Label miss;
|
||||
|
||||
__ save_frame(0); // Blow no registers!
|
||||
|
||||
__ ld_ptr( G3, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), L3 );
|
||||
__ lduw(L3,arrayOopDesc::length_offset_in_bytes(),L0); // length in l0
|
||||
__ add(L3,arrayOopDesc::base_offset_in_bytes(T_OBJECT),L1); // ptr into array
|
||||
__ clr(L4); // Index
|
||||
// Load a little early; will load 1 off the end of the array.
|
||||
// Ok for now; revisit if we have other uses of this routine.
|
||||
__ ld_ptr(L1,0,L2); // Will load a little early
|
||||
|
||||
// The scan loop
|
||||
__ bind(loop);
|
||||
__ add(L1,wordSize,L1); // Bump by OOP size
|
||||
__ cmp(L4,L0);
|
||||
__ br(Assembler::equal,false,Assembler::pn,miss);
|
||||
__ delayed()->inc(L4); // Bump index
|
||||
__ subcc(L2,G1,L3); // Check for match; zero in L3 for a hit
|
||||
__ brx( Assembler::notEqual, false, Assembler::pt, loop );
|
||||
__ delayed()->ld_ptr(L1,0,L2); // Will load a little early
|
||||
|
||||
// Got a hit; report success; set cache
|
||||
__ st_ptr( G1, G3, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
|
||||
__ check_klass_subtype_slow_path(G3, G1, L0, L1, L2, L4, NULL, &miss);
|
||||
|
||||
__ mov(1, G3);
|
||||
__ ret(); // Result in G5 is ok; flags set
|
||||
__ ret(); // Result in G5 is 'true'
|
||||
__ delayed()->restore(); // free copy or add can go here
|
||||
|
||||
__ bind(miss);
|
||||
__ mov(0, G3);
|
||||
__ ret(); // Result in G5 is ok; flags set
|
||||
__ ret(); // Result in G5 is 'false'
|
||||
__ delayed()->restore(); // free copy or add can go here
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ define_pd_global(uintx, TLABSize, 0);
|
||||
define_pd_global(uintx, NewSize, ScaleForWordSize((2048 * K) + (2 * (64 * K))));
|
||||
define_pd_global(intx, SurvivorRatio, 8);
|
||||
define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
|
||||
define_pd_global(intx, InlineSmallCode, 1500);
|
||||
#ifdef _LP64
|
||||
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
|
||||
define_pd_global(intx, ThreadStackSize, 1024);
|
||||
|
@ -866,65 +866,18 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
|
||||
Register Rtmp2,
|
||||
Register Rtmp3,
|
||||
Label &ok_is_subtype ) {
|
||||
Label not_subtype, loop;
|
||||
Label not_subtype;
|
||||
|
||||
// Profile the not-null value's klass.
|
||||
profile_typecheck(Rsub_klass, Rtmp1);
|
||||
|
||||
// Load the super-klass's check offset into Rtmp1
|
||||
ld( Rsuper_klass, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1 );
|
||||
// Load from the sub-klass's super-class display list, or a 1-word cache of
|
||||
// the secondary superclass list, or a failing value with a sentinel offset
|
||||
// if the super-klass is an interface or exceptionally deep in the Java
|
||||
// hierarchy and we have to scan the secondary superclass list the hard way.
|
||||
ld_ptr( Rsub_klass, Rtmp1, Rtmp2 );
|
||||
// See if we get an immediate positive hit
|
||||
cmp( Rtmp2, Rsuper_klass );
|
||||
brx( Assembler::equal, false, Assembler::pt, ok_is_subtype );
|
||||
// In the delay slot, check for immediate negative hit
|
||||
delayed()->cmp( Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
|
||||
br( Assembler::notEqual, false, Assembler::pt, not_subtype );
|
||||
// In the delay slot, check for self
|
||||
delayed()->cmp( Rsub_klass, Rsuper_klass );
|
||||
brx( Assembler::equal, false, Assembler::pt, ok_is_subtype );
|
||||
check_klass_subtype_fast_path(Rsub_klass, Rsuper_klass,
|
||||
Rtmp1, Rtmp2,
|
||||
&ok_is_subtype, ¬_subtype, NULL);
|
||||
|
||||
// Now do a linear scan of the secondary super-klass chain.
|
||||
delayed()->ld_ptr( Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), Rtmp2 );
|
||||
|
||||
// compress superclass
|
||||
if (UseCompressedOops) encode_heap_oop(Rsuper_klass);
|
||||
|
||||
// Rtmp2 holds the objArrayOop of secondary supers.
|
||||
ld( Rtmp2, arrayOopDesc::length_offset_in_bytes(), Rtmp1 );// Load the array length
|
||||
// Check for empty secondary super list
|
||||
tst(Rtmp1);
|
||||
|
||||
// Top of search loop
|
||||
bind( loop );
|
||||
br( Assembler::equal, false, Assembler::pn, not_subtype );
|
||||
delayed()->nop();
|
||||
|
||||
// load next super to check
|
||||
if (UseCompressedOops) {
|
||||
lduw( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
|
||||
// Bump array pointer forward one oop
|
||||
add( Rtmp2, 4, Rtmp2 );
|
||||
} else {
|
||||
ld_ptr( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
|
||||
// Bump array pointer forward one oop
|
||||
add( Rtmp2, wordSize, Rtmp2);
|
||||
}
|
||||
// Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list
|
||||
cmp( Rtmp3, Rsuper_klass );
|
||||
// A miss means we are NOT a subtype and need to keep looping
|
||||
brx( Assembler::notEqual, false, Assembler::pt, loop );
|
||||
delayed()->deccc( Rtmp1 ); // dec trip counter in delay slot
|
||||
// Falling out the bottom means we found a hit; we ARE a subtype
|
||||
if (UseCompressedOops) decode_heap_oop(Rsuper_klass);
|
||||
br( Assembler::always, false, Assembler::pt, ok_is_subtype );
|
||||
// Update the cache
|
||||
delayed()->st_ptr( Rsuper_klass, Rsub_klass,
|
||||
sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
|
||||
check_klass_subtype_slow_path(Rsub_klass, Rsuper_klass,
|
||||
Rtmp1, Rtmp2, Rtmp3, /*hack:*/ noreg,
|
||||
&ok_is_subtype, NULL);
|
||||
|
||||
bind(not_subtype);
|
||||
profile_typecheck_failed(Rtmp1);
|
||||
@ -2465,7 +2418,10 @@ void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
|
||||
// InterpreterRuntime::post_method_entry();
|
||||
// }
|
||||
// if (DTraceMethodProbes) {
|
||||
// SharedRuntime::dtrace_method_entry(method, reciever);
|
||||
// SharedRuntime::dtrace_method_entry(method, receiver);
|
||||
// }
|
||||
// if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
|
||||
// SharedRuntime::rc_trace_method_entry(method, receiver);
|
||||
// }
|
||||
|
||||
void InterpreterMacroAssembler::notify_method_entry() {
|
||||
@ -2497,6 +2453,13 @@ void InterpreterMacroAssembler::notify_method_entry() {
|
||||
CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
|
||||
G2_thread, Lmethod);
|
||||
}
|
||||
|
||||
// RedefineClasses() tracing support for obsolete method entry
|
||||
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
|
||||
call_VM_leaf(noreg,
|
||||
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
|
||||
G2_thread, Lmethod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
|
@ -243,7 +243,7 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
// Regenerate the instruction sequence that performs the 64 bit
|
||||
// sethi. This only does the sethi. The disp field (bottom 10 bits)
|
||||
// must be handled seperately.
|
||||
// must be handled separately.
|
||||
static void set_data64_sethi(address instaddr, intptr_t x);
|
||||
|
||||
// combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st)
|
||||
|
@ -2161,6 +2161,18 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
__ restore();
|
||||
}
|
||||
|
||||
// RedefineClasses() tracing support for obsolete method entry
|
||||
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
|
||||
// create inner frame
|
||||
__ save_frame(0);
|
||||
__ mov(G2_thread, L7_thread_cache);
|
||||
__ set_oop_constant(JNIHandles::make_local(method()), O1);
|
||||
__ call_VM_leaf(L7_thread_cache,
|
||||
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
|
||||
G2_thread, O1);
|
||||
__ restore();
|
||||
}
|
||||
|
||||
// We are in the jni frame unless saved_frame is true in which case
|
||||
// we are in one frame deeper (the "inner" frame). If we are in the
|
||||
// "inner" frames the args are in the Iregs and if the jni frame then
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
// Copyright 1998-2009 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
|
||||
@ -189,7 +189,7 @@ reg_def R_F31( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
|
||||
// double fp register numbers. FloatRegisterImpl in register_sparc.hpp
|
||||
// wants 0-63, so we have to convert every time we want to use fp regs
|
||||
// with the macroassembler, using reg_to_DoubleFloatRegister_object().
|
||||
// 255 is a flag meaning 'dont go here'.
|
||||
// 255 is a flag meaning "don't go here".
|
||||
// I believe we can't handle callee-save doubles D32 and up until
|
||||
// the place in the sparc stack crawler that asserts on the 255 is
|
||||
// fixed up.
|
||||
@ -462,7 +462,7 @@ extern bool can_branch_register( Node *bol, Node *cmp );
|
||||
|
||||
// Macros to extract hi & lo halves from a long pair.
|
||||
// G0 is not part of any long pair, so assert on that.
|
||||
// Prevents accidently using G1 instead of G0.
|
||||
// Prevents accidentally using G1 instead of G0.
|
||||
#define LONG_HI_REG(x) (x)
|
||||
#define LONG_LO_REG(x) (x)
|
||||
|
||||
@ -547,7 +547,11 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
|
||||
int klass_load_size;
|
||||
if (UseCompressedOops) {
|
||||
klass_load_size = 3*BytesPerInstWord; // see MacroAssembler::load_klass()
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
if (Universe::narrow_oop_base() == NULL)
|
||||
klass_load_size = 2*BytesPerInstWord; // see MacroAssembler::load_klass()
|
||||
else
|
||||
klass_load_size = 3*BytesPerInstWord;
|
||||
} else {
|
||||
klass_load_size = 1*BytesPerInstWord;
|
||||
}
|
||||
@ -1431,7 +1435,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
|
||||
|
||||
#ifndef _LP64
|
||||
// In the LP64 build, all registers can be moved as aligned/adjacent
|
||||
// pairs, so there's never any need to move the high bits seperately.
|
||||
// pairs, so there's never any need to move the high bits separately.
|
||||
// The 32-bit builds have to deal with the 32-bit ABI which can force
|
||||
// all sorts of silly alignment problems.
|
||||
|
||||
@ -1601,8 +1605,10 @@ void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
|
||||
st->print_cr("\nUEP:");
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
|
||||
st->print_cr("\tSLL R_G5,3,R_G5");
|
||||
if (Universe::narrow_oop_base() != NULL)
|
||||
st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
|
||||
} else {
|
||||
st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
|
||||
@ -1624,7 +1630,7 @@ void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||
Register temp_reg = G3;
|
||||
assert( G5_ic_reg != temp_reg, "conflicting registers" );
|
||||
|
||||
// Load klass from reciever
|
||||
// Load klass from receiver
|
||||
__ load_klass(O0, temp_reg);
|
||||
// Compare against expected klass
|
||||
__ cmp(temp_reg, G5_ic_reg);
|
||||
@ -2502,6 +2508,10 @@ encode %{
|
||||
__ load_klass(O0, G3_scratch);
|
||||
int klass_load_size;
|
||||
if (UseCompressedOops) {
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
if (Universe::narrow_oop_base() == NULL)
|
||||
klass_load_size = 2*BytesPerInstWord;
|
||||
else
|
||||
klass_load_size = 3*BytesPerInstWord;
|
||||
} else {
|
||||
klass_load_size = 1*BytesPerInstWord;
|
||||
@ -2993,6 +3003,202 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
||||
__ bind(Ldone);
|
||||
%}
|
||||
|
||||
enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
|
||||
Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
Register str1_reg = reg_to_register_object($str1$$reg);
|
||||
Register str2_reg = reg_to_register_object($str2$$reg);
|
||||
Register tmp1_reg = reg_to_register_object($tmp1$$reg);
|
||||
Register tmp2_reg = reg_to_register_object($tmp2$$reg);
|
||||
Register result_reg = reg_to_register_object($result$$reg);
|
||||
|
||||
// Get the first character position in both strings
|
||||
// [8] char array, [12] offset, [16] count
|
||||
int value_offset = java_lang_String:: value_offset_in_bytes();
|
||||
int offset_offset = java_lang_String::offset_offset_in_bytes();
|
||||
int count_offset = java_lang_String:: count_offset_in_bytes();
|
||||
|
||||
// load str1 (jchar*) base address into tmp1_reg
|
||||
__ load_heap_oop(Address(str1_reg, 0, value_offset), tmp1_reg);
|
||||
__ ld(Address(str1_reg, 0, offset_offset), result_reg);
|
||||
__ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
|
||||
__ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted
|
||||
__ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
|
||||
__ load_heap_oop(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
|
||||
__ add(result_reg, tmp1_reg, tmp1_reg);
|
||||
|
||||
// load str2 (jchar*) base address into tmp2_reg
|
||||
// __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
|
||||
__ ld(Address(str2_reg, 0, offset_offset), result_reg);
|
||||
__ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
|
||||
__ ld(Address(str2_reg, 0, count_offset), str2_reg); // hoisted
|
||||
__ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
|
||||
__ cmp(str1_reg, str2_reg); // hoisted
|
||||
__ add(result_reg, tmp2_reg, tmp2_reg);
|
||||
|
||||
__ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg);
|
||||
__ br(Assembler::notEqual, true, Assembler::pt, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); // not equal
|
||||
|
||||
__ br_zero(Assembler::equal, true, Assembler::pn, str1_reg, Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg); //equals
|
||||
|
||||
__ cmp(tmp1_reg, tmp2_reg); //same string ?
|
||||
__ brx(Assembler::equal, true, Assembler::pn, Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg);
|
||||
|
||||
//rename registers
|
||||
Register limit_reg = str1_reg;
|
||||
Register chr2_reg = str2_reg;
|
||||
Register chr1_reg = result_reg;
|
||||
// tmp{12} are the base pointers
|
||||
|
||||
//check for alignment and position the pointers to the ends
|
||||
__ or3(tmp1_reg, tmp2_reg, chr1_reg);
|
||||
__ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
|
||||
__ br(Assembler::notZero, false, Assembler::pn, Lchar);
|
||||
__ delayed()->nop();
|
||||
|
||||
__ bind(Lword);
|
||||
__ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2)
|
||||
__ andn(limit_reg, 0x3, limit_reg);
|
||||
__ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
|
||||
__ delayed()->nop();
|
||||
|
||||
__ add(tmp1_reg, limit_reg, tmp1_reg);
|
||||
__ add(tmp2_reg, limit_reg, tmp2_reg);
|
||||
__ neg(limit_reg);
|
||||
|
||||
__ lduw(tmp1_reg, limit_reg, chr1_reg);
|
||||
__ bind(Lword_loop);
|
||||
__ lduw(tmp2_reg, limit_reg, chr2_reg);
|
||||
__ cmp(chr1_reg, chr2_reg);
|
||||
__ br(Assembler::notEqual, true, Assembler::pt, Ldone);
|
||||
__ delayed()->mov(G0, result_reg);
|
||||
__ inccc(limit_reg, 2*sizeof(jchar));
|
||||
// annul LDUW if branch i s not taken to prevent access past end of string
|
||||
__ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
|
||||
__ delayed()->lduw(tmp1_reg, limit_reg, chr1_reg); // hoisted
|
||||
|
||||
__ bind(Lpost_word);
|
||||
__ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg);
|
||||
|
||||
__ lduh(tmp1_reg, 0, chr1_reg);
|
||||
__ lduh(tmp2_reg, 0, chr2_reg);
|
||||
__ cmp (chr1_reg, chr2_reg);
|
||||
__ br(Assembler::notEqual, true, Assembler::pt, Ldone);
|
||||
__ delayed()->mov(G0, result_reg);
|
||||
__ ba(false,Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg);
|
||||
|
||||
__ bind(Lchar);
|
||||
__ add(tmp1_reg, limit_reg, tmp1_reg);
|
||||
__ add(tmp2_reg, limit_reg, tmp2_reg);
|
||||
__ neg(limit_reg); //negate count
|
||||
|
||||
__ lduh(tmp1_reg, limit_reg, chr1_reg);
|
||||
__ bind(Lchar_loop);
|
||||
__ lduh(tmp2_reg, limit_reg, chr2_reg);
|
||||
__ cmp(chr1_reg, chr2_reg);
|
||||
__ br(Assembler::notEqual, true, Assembler::pt, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); //not equal
|
||||
__ inccc(limit_reg, sizeof(jchar));
|
||||
// annul LDUH if branch is not taken to prevent access past end of string
|
||||
__ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
|
||||
__ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
|
||||
|
||||
__ add(G0, 1, result_reg); //equal
|
||||
|
||||
__ bind(Ldone);
|
||||
%}
|
||||
|
||||
enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
|
||||
Label Lvector, Ldone, Lloop;
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
Register ary1_reg = reg_to_register_object($ary1$$reg);
|
||||
Register ary2_reg = reg_to_register_object($ary2$$reg);
|
||||
Register tmp1_reg = reg_to_register_object($tmp1$$reg);
|
||||
Register tmp2_reg = reg_to_register_object($tmp2$$reg);
|
||||
Register result_reg = reg_to_register_object($result$$reg);
|
||||
|
||||
int length_offset = arrayOopDesc::length_offset_in_bytes();
|
||||
int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
|
||||
|
||||
// return true if the same array
|
||||
__ cmp(ary1_reg, ary2_reg);
|
||||
__ br(Assembler::equal, true, Assembler::pn, Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg); // equal
|
||||
|
||||
__ br_null(ary1_reg, true, Assembler::pn, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); // not equal
|
||||
|
||||
__ br_null(ary2_reg, true, Assembler::pn, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); // not equal
|
||||
|
||||
//load the lengths of arrays
|
||||
__ ld(Address(ary1_reg, 0, length_offset), tmp1_reg);
|
||||
__ ld(Address(ary2_reg, 0, length_offset), tmp2_reg);
|
||||
|
||||
// return false if the two arrays are not equal length
|
||||
__ cmp(tmp1_reg, tmp2_reg);
|
||||
__ br(Assembler::notEqual, true, Assembler::pn, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); // not equal
|
||||
|
||||
__ br_zero(Assembler::zero, true, Assembler::pn, tmp1_reg, Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
|
||||
|
||||
// load array addresses
|
||||
__ add(ary1_reg, base_offset, ary1_reg);
|
||||
__ add(ary2_reg, base_offset, ary2_reg);
|
||||
|
||||
// renaming registers
|
||||
Register chr1_reg = tmp2_reg; // for characters in ary1
|
||||
Register chr2_reg = result_reg; // for characters in ary2
|
||||
Register limit_reg = tmp1_reg; // length
|
||||
|
||||
// set byte count
|
||||
__ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
|
||||
__ andcc(limit_reg, 0x2, chr1_reg); //trailing character ?
|
||||
__ br(Assembler::zero, false, Assembler::pt, Lvector);
|
||||
__ delayed()->nop();
|
||||
|
||||
//compare the trailing char
|
||||
__ sub(limit_reg, sizeof(jchar), limit_reg);
|
||||
__ lduh(ary1_reg, limit_reg, chr1_reg);
|
||||
__ lduh(ary2_reg, limit_reg, chr2_reg);
|
||||
__ cmp(chr1_reg, chr2_reg);
|
||||
__ br(Assembler::notEqual, true, Assembler::pt, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); // not equal
|
||||
|
||||
// only one char ?
|
||||
__ br_zero(Assembler::zero, true, Assembler::pn, limit_reg, Ldone);
|
||||
__ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
|
||||
|
||||
__ bind(Lvector);
|
||||
// Shift ary1_reg and ary2_reg to the end of the arrays, negate limit
|
||||
__ add(ary1_reg, limit_reg, ary1_reg);
|
||||
__ add(ary2_reg, limit_reg, ary2_reg);
|
||||
__ neg(limit_reg, limit_reg);
|
||||
|
||||
__ lduw(ary1_reg, limit_reg, chr1_reg);
|
||||
__ bind(Lloop);
|
||||
__ lduw(ary2_reg, limit_reg, chr2_reg);
|
||||
__ cmp(chr1_reg, chr2_reg);
|
||||
__ br(Assembler::notEqual, false, Assembler::pt, Ldone);
|
||||
__ delayed()->mov(G0, result_reg); // not equal
|
||||
__ inccc(limit_reg, 2*sizeof(jchar));
|
||||
// annul LDUW if branch is not taken to prevent access past end of string
|
||||
__ br(Assembler::notZero, true, Assembler::pt, Lloop); //annul on taken
|
||||
__ delayed()->lduw(ary1_reg, limit_reg, chr1_reg); // hoisted
|
||||
|
||||
__ add(G0, 1, result_reg); // equals
|
||||
|
||||
__ bind(Ldone);
|
||||
%}
|
||||
|
||||
enc_class enc_rethrow() %{
|
||||
cbuf.set_inst_mark();
|
||||
Register temp_reg = G3;
|
||||
@ -4149,7 +4355,7 @@ operand cmpOp_commute() %{
|
||||
|
||||
//----------OPERAND CLASSES----------------------------------------------------
|
||||
// Operand Classes are groups of operands that are used to simplify
|
||||
// instruction definitions by not requiring the AD writer to specify seperate
|
||||
// instruction definitions by not requiring the AD writer to specify separate
|
||||
// instructions for every form of operand when the instruction accepts
|
||||
// multiple operand types with the same basic encoding and format. The classic
|
||||
// case of this is memory operands.
|
||||
@ -5286,55 +5492,91 @@ instruct loadB(iRegI dst, memory mem) %{
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDSB $mem,$dst" %}
|
||||
format %{ "LDSB $mem,$dst\t! byte" %}
|
||||
opcode(Assembler::ldsb_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Byte (8bit UNsigned) into an int reg
|
||||
instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{
|
||||
match(Set dst (AndI (LoadB mem) bytemask));
|
||||
// Load Byte (8bit signed) into a Long Register
|
||||
instruct loadB2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadB mem)));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUB $mem,$dst" %}
|
||||
format %{ "LDSB $mem,$dst\t! byte -> long" %}
|
||||
opcode(Assembler::ldsb_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Byte (8bit UNsigned) into an int reg
|
||||
instruct loadUB(iRegI dst, memory mem) %{
|
||||
match(Set dst (LoadUB mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUB $mem,$dst\t! ubyte" %}
|
||||
opcode(Assembler::ldub_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Byte (8bit UNsigned) into a Long Register
|
||||
instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{
|
||||
match(Set dst (AndL (ConvI2L (LoadB mem)) bytemask));
|
||||
// Load Unsigned Byte (8bit UNsigned) into a Long Register
|
||||
instruct loadUB2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadUB mem)));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUB $mem,$dst" %}
|
||||
format %{ "LDUB $mem,$dst\t! ubyte -> long" %}
|
||||
opcode(Assembler::ldub_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
|
||||
instruct loadUS2L(iRegL dst, memory mem, immL_FFFF bytemask) %{
|
||||
match(Set dst (AndL (ConvI2L (LoadUS mem)) bytemask));
|
||||
// Load Short (16bit signed)
|
||||
instruct loadS(iRegI dst, memory mem) %{
|
||||
match(Set dst (LoadS mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUH $mem,$dst" %}
|
||||
opcode(Assembler::lduh_op3);
|
||||
format %{ "LDSH $mem,$dst\t! short" %}
|
||||
opcode(Assembler::ldsh_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16bit unsigned)
|
||||
// Load Short (16bit signed) into a Long Register
|
||||
instruct loadS2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadS mem)));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDSH $mem,$dst\t! short -> long" %}
|
||||
opcode(Assembler::ldsh_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16bit UNsigned)
|
||||
instruct loadUS(iRegI dst, memory mem) %{
|
||||
match(Set dst (LoadUS mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUH $mem,$dst" %}
|
||||
format %{ "LDUH $mem,$dst\t! ushort/char" %}
|
||||
opcode(Assembler::lduh_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
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)));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUH $mem,$dst\t! ushort/char -> long" %}
|
||||
opcode(Assembler::lduh_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
@ -5344,9 +5586,33 @@ instruct loadUS(iRegI dst, memory mem) %{
|
||||
instruct loadI(iRegI dst, memory mem) %{
|
||||
match(Set dst (LoadI mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
size(4);
|
||||
|
||||
format %{ "LDUW $mem,$dst" %}
|
||||
size(4);
|
||||
format %{ "LDUW $mem,$dst\t! int" %}
|
||||
opcode(Assembler::lduw_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mem);
|
||||
%}
|
||||
|
||||
// Load Integer into a Long Register
|
||||
instruct loadI2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadI mem)));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDSW $mem,$dst\t! int -> long" %}
|
||||
opcode(Assembler::ldsw_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Integer into a Long Register
|
||||
instruct loadUI2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (LoadUI2L mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDUW $mem,$dst\t! uint -> long" %}
|
||||
opcode(Assembler::lduw_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mem);
|
||||
@ -5356,6 +5622,7 @@ instruct loadI(iRegI dst, memory mem) %{
|
||||
instruct loadL(iRegL dst, memory mem ) %{
|
||||
match(Set dst (LoadL mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDX $mem,$dst\t! long" %}
|
||||
opcode(Assembler::ldx_op3);
|
||||
@ -5471,13 +5738,11 @@ instruct loadN(iRegN dst, memory mem) %{
|
||||
|
||||
format %{ "LDUW $mem,$dst\t! compressed ptr" %}
|
||||
ins_encode %{
|
||||
Register base = as_Register($mem$$base);
|
||||
Register index = as_Register($mem$$index);
|
||||
Register dst = $dst$$Register;
|
||||
Register index = $mem$$index$$Register;
|
||||
if (index != G0) {
|
||||
__ lduw(base, index, dst);
|
||||
__ lduw($mem$$base$$Register, index, $dst$$Register);
|
||||
} else {
|
||||
__ lduw(base, $mem$$disp, dst);
|
||||
__ lduw($mem$$base$$Register, $mem$$disp, $dst$$Register);
|
||||
}
|
||||
%}
|
||||
ins_pipe(iload_mem);
|
||||
@ -5521,18 +5786,6 @@ instruct loadNKlass(iRegN dst, memory mem) %{
|
||||
ins_pipe(iload_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16bit signed)
|
||||
instruct loadS(iRegI dst, memory mem) %{
|
||||
match(Set dst (LoadS mem));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDSH $mem,$dst" %}
|
||||
opcode(Assembler::ldsh_op3);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Double
|
||||
instruct loadD(regD dst, memory mem) %{
|
||||
match(Set dst (LoadD mem));
|
||||
@ -6847,7 +7100,7 @@ instruct mul_hi(iRegIsafe dst, iRegIsafe src1, iRegIsafe src2 ) %{
|
||||
ins_pipe(sdiv_reg_reg);
|
||||
%}
|
||||
|
||||
// Magic constant, reciprical of 10
|
||||
// Magic constant, reciprocal of 10
|
||||
instruct loadConI_x66666667(iRegIsafe dst) %{
|
||||
effect( DEF dst );
|
||||
|
||||
@ -6857,7 +7110,7 @@ instruct loadConI_x66666667(iRegIsafe dst) %{
|
||||
ins_pipe(ialu_hi_lo_reg);
|
||||
%}
|
||||
|
||||
// Register Shift Right Arithmatic Long by 32-63
|
||||
// Register Shift Right Arithmetic Long by 32-63
|
||||
instruct sra_31( iRegI dst, iRegI src ) %{
|
||||
effect( DEF dst, USE src );
|
||||
format %{ "SRA $src,31,$dst\t! Used in div-by-10" %}
|
||||
@ -8958,6 +9211,52 @@ instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, note
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
|
||||
o7RegI tmp3, flagsReg ccr) %{
|
||||
match(Set result (StrEquals str1 str2));
|
||||
effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
|
||||
ins_cost(300);
|
||||
format %{ "String Equals $str1,$str2 -> $result" %}
|
||||
ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) );
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
|
||||
flagsReg ccr) %{
|
||||
match(Set result (AryEq ary1 ary2));
|
||||
effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
|
||||
ins_cost(300);
|
||||
format %{ "Array Equals $ary1,$ary2 -> $result" %}
|
||||
ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
//---------- Population Count Instructions -------------------------------------
|
||||
|
||||
instruct popCountI(iRegI dst, iRegI src) %{
|
||||
predicate(UsePopCountInstruction);
|
||||
match(Set dst (PopCountI src));
|
||||
|
||||
format %{ "POPC $src, $dst" %}
|
||||
ins_encode %{
|
||||
__ popc($src$$Register, $dst$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
// Note: Long.bitCount(long) returns an int.
|
||||
instruct popCountL(iRegI dst, iRegL src) %{
|
||||
predicate(UsePopCountInstruction);
|
||||
match(Set dst (PopCountL src));
|
||||
|
||||
format %{ "POPC $src, $dst" %}
|
||||
ins_encode %{
|
||||
__ popc($src$$Register, $dst$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//------------Bytes reverse--------------------------------------------------
|
||||
|
||||
@ -9048,7 +9347,7 @@ instruct storeL_reversed(memory dst, iRegL src) %{
|
||||
// These must follow all instruction definitions as they use the names
|
||||
// defined in the instructions definitions.
|
||||
//
|
||||
// peepmatch ( root_instr_name [preceeding_instruction]* );
|
||||
// peepmatch ( root_instr_name [preceding_instruction]* );
|
||||
//
|
||||
// peepconstraint %{
|
||||
// (instruction_number.operand_name relational_op instruction_number.operand_name
|
||||
|
@ -817,21 +817,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Label _atomic_add_stub; // called from other stubs
|
||||
|
||||
|
||||
// Support for void OrderAccess::fence().
|
||||
//
|
||||
address generate_fence() {
|
||||
StubCodeMark mark(this, "StubRoutines", "fence");
|
||||
address start = __ pc();
|
||||
|
||||
__ membar(Assembler::Membar_mask_bits(Assembler::LoadLoad | Assembler::LoadStore |
|
||||
Assembler::StoreLoad | Assembler::StoreStore));
|
||||
__ retl(false);
|
||||
__ delayed()->nop();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// The following routine generates a subroutine to throw an asynchronous
|
||||
// UnknownError when an unsafe access gets a fault that could not be
|
||||
@ -900,19 +885,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(this, "StubRoutines", "partial_subtype_check");
|
||||
address start = __ pc();
|
||||
Label loop, miss;
|
||||
|
||||
// Compare super with sub directly, since super is not in its own SSA.
|
||||
// The compiler used to emit this test, but we fold it in here,
|
||||
// to increase overall code density, with no real loss of speed.
|
||||
{ Label L;
|
||||
__ cmp(O1, O2);
|
||||
__ brx(Assembler::notEqual, false, Assembler::pt, L);
|
||||
__ delayed()->nop();
|
||||
__ retl();
|
||||
__ delayed()->addcc(G0,0,O0); // set Z flags, zero result
|
||||
__ bind(L);
|
||||
}
|
||||
Label miss;
|
||||
|
||||
#if defined(COMPILER2) && !defined(_LP64)
|
||||
// Do not use a 'save' because it blows the 64-bit O registers.
|
||||
@ -936,56 +909,12 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Register L2_super = L2;
|
||||
Register L3_index = L3;
|
||||
|
||||
#ifdef _LP64
|
||||
Register L4_ooptmp = L4;
|
||||
__ check_klass_subtype_slow_path(Rsub, Rsuper,
|
||||
L0, L1, L2, L3,
|
||||
NULL, &miss);
|
||||
|
||||
if (UseCompressedOops) {
|
||||
// this must be under UseCompressedOops check, as we rely upon fact
|
||||
// that L4 not clobbered in C2 on 32-bit platforms, where we do explicit save
|
||||
// on stack, see several lines above
|
||||
__ encode_heap_oop(Rsuper, L4_ooptmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
inc_counter_np(SharedRuntime::_partial_subtype_ctr, L0, L1);
|
||||
|
||||
__ ld_ptr( Rsub, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), L3 );
|
||||
__ lduw(L3,arrayOopDesc::length_offset_in_bytes(),L0_ary_len);
|
||||
__ add(L3,arrayOopDesc::base_offset_in_bytes(T_OBJECT),L1_ary_ptr);
|
||||
__ clr(L3_index); // zero index
|
||||
// Load a little early; will load 1 off the end of the array.
|
||||
// Ok for now; revisit if we have other uses of this routine.
|
||||
if (UseCompressedOops) {
|
||||
__ lduw(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||
} else {
|
||||
__ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||
}
|
||||
|
||||
assert(heapOopSize != 0, "heapOopSize should be initialized");
|
||||
// The scan loop
|
||||
__ BIND(loop);
|
||||
__ add(L1_ary_ptr, heapOopSize, L1_ary_ptr); // Bump by OOP size
|
||||
__ cmp(L3_index,L0_ary_len);
|
||||
__ br(Assembler::equal,false,Assembler::pn,miss);
|
||||
__ delayed()->inc(L3_index); // Bump index
|
||||
|
||||
if (UseCompressedOops) {
|
||||
#ifdef _LP64
|
||||
__ subcc(L2_super,L4_ooptmp,Rret); // Check for match; zero in Rret for a hit
|
||||
__ br( Assembler::notEqual, false, Assembler::pt, loop );
|
||||
__ delayed()->lduw(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||
#else
|
||||
ShouldNotReachHere();
|
||||
#endif
|
||||
} else {
|
||||
__ subcc(L2_super,Rsuper,Rret); // Check for match; zero in Rret for a hit
|
||||
__ brx( Assembler::notEqual, false, Assembler::pt, loop );
|
||||
__ delayed()->ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||
}
|
||||
|
||||
// Got a hit; report success; set cache. Cache load doesn't
|
||||
// happen here; for speed it is directly emitted by the compiler.
|
||||
__ st_ptr( Rsuper, Rsub, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
|
||||
// Match falls through here.
|
||||
__ addcc(G0,0,Rret); // set Z flags, Z result
|
||||
|
||||
#if defined(COMPILER2) && !defined(_LP64)
|
||||
__ ld_ptr(SP,(frame::register_save_words+0)*wordSize,L0);
|
||||
@ -999,7 +928,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ delayed()->restore();
|
||||
#endif
|
||||
|
||||
// Hit or miss falls through here
|
||||
__ BIND(miss);
|
||||
__ addcc(G0,1,Rret); // set NZ flags, NZ result
|
||||
|
||||
@ -2330,51 +2258,31 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Register super_check_offset,
|
||||
Register super_klass,
|
||||
Register temp,
|
||||
Label& L_success,
|
||||
Register deccc_hack = noreg) {
|
||||
Label& L_success) {
|
||||
assert_different_registers(sub_klass, super_check_offset, super_klass, temp);
|
||||
|
||||
BLOCK_COMMENT("type_check:");
|
||||
|
||||
Label L_miss;
|
||||
Label L_miss, L_pop_to_miss;
|
||||
|
||||
assert_clean_int(super_check_offset, temp);
|
||||
|
||||
// maybe decrement caller's trip count:
|
||||
#define DELAY_SLOT delayed(); \
|
||||
{ if (deccc_hack == noreg) __ nop(); else __ deccc(deccc_hack); }
|
||||
|
||||
// if the pointers are equal, we are done (e.g., String[] elements)
|
||||
__ cmp(sub_klass, super_klass);
|
||||
__ brx(Assembler::equal, true, Assembler::pt, L_success);
|
||||
__ DELAY_SLOT;
|
||||
|
||||
// check the supertype display:
|
||||
__ ld_ptr(sub_klass, super_check_offset, temp); // query the super type
|
||||
__ cmp(super_klass, temp); // test the super type
|
||||
__ brx(Assembler::equal, true, Assembler::pt, L_success);
|
||||
__ DELAY_SLOT;
|
||||
|
||||
int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ cmp(super_klass, sc_offset);
|
||||
__ brx(Assembler::notEqual, true, Assembler::pt, L_miss);
|
||||
__ delayed()->nop();
|
||||
__ check_klass_subtype_fast_path(sub_klass, super_klass, temp, noreg,
|
||||
&L_success, &L_miss, NULL,
|
||||
super_check_offset);
|
||||
|
||||
BLOCK_COMMENT("type_check_slow_path:");
|
||||
__ save_frame(0);
|
||||
__ mov(sub_klass->after_save(), O1);
|
||||
// mov(super_klass->after_save(), O2); //fill delay slot
|
||||
assert(StubRoutines::Sparc::_partial_subtype_check != NULL, "order of generation");
|
||||
__ call(StubRoutines::Sparc::_partial_subtype_check);
|
||||
__ delayed()->mov(super_klass->after_save(), O2);
|
||||
__ check_klass_subtype_slow_path(sub_klass->after_save(),
|
||||
super_klass->after_save(),
|
||||
L0, L1, L2, L4,
|
||||
NULL, &L_pop_to_miss);
|
||||
__ ba(false, L_success);
|
||||
__ delayed()->restore();
|
||||
|
||||
__ bind(L_pop_to_miss);
|
||||
__ restore();
|
||||
|
||||
// Upon return, the condition codes are already set.
|
||||
__ brx(Assembler::equal, true, Assembler::pt, L_success);
|
||||
__ DELAY_SLOT;
|
||||
|
||||
#undef DELAY_SLOT
|
||||
|
||||
// Fall through on failure!
|
||||
__ BIND(L_miss);
|
||||
}
|
||||
@ -2411,7 +2319,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
gen_write_ref_array_pre_barrier(O1, O2);
|
||||
|
||||
#ifdef ASSERT
|
||||
// We sometimes save a frame (see partial_subtype_check below).
|
||||
// We sometimes save a frame (see generate_type_check below).
|
||||
// If this will cause trouble, let's fail now instead of later.
|
||||
__ save_frame(0);
|
||||
__ restore();
|
||||
@ -2455,41 +2363,39 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// G3, G4, G5 --- current oop, oop.klass, oop.klass.super
|
||||
__ align(16);
|
||||
|
||||
__ bind(store_element);
|
||||
// deccc(G1_remain); // decrement the count (hoisted)
|
||||
__ BIND(store_element);
|
||||
__ deccc(G1_remain); // decrement the count
|
||||
__ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop
|
||||
__ inc(O5_offset, heapOopSize); // step to next offset
|
||||
__ brx(Assembler::zero, true, Assembler::pt, do_card_marks);
|
||||
__ delayed()->set(0, O0); // return -1 on success
|
||||
|
||||
// ======== loop entry is here ========
|
||||
__ bind(load_element);
|
||||
__ BIND(load_element);
|
||||
__ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop
|
||||
__ br_null(G3_oop, true, Assembler::pt, store_element);
|
||||
__ delayed()->deccc(G1_remain); // decrement the count
|
||||
__ delayed()->nop();
|
||||
|
||||
__ load_klass(G3_oop, G4_klass); // query the object klass
|
||||
|
||||
generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super,
|
||||
// branch to this on success:
|
||||
store_element,
|
||||
// decrement this on success:
|
||||
G1_remain);
|
||||
store_element);
|
||||
// ======== end loop ========
|
||||
|
||||
// It was a real error; we must depend on the caller to finish the job.
|
||||
// Register G1 has number of *remaining* oops, O2 number of *total* oops.
|
||||
// Emit GC store barriers for the oops we have copied (O2 minus G1),
|
||||
// and report their number to the caller.
|
||||
__ bind(fail);
|
||||
__ BIND(fail);
|
||||
__ subcc(O2_count, G1_remain, O2_count);
|
||||
__ brx(Assembler::zero, false, Assembler::pt, done);
|
||||
__ delayed()->not1(O2_count, O0); // report (-1^K) to caller
|
||||
|
||||
__ bind(do_card_marks);
|
||||
__ BIND(do_card_marks);
|
||||
gen_write_ref_array_post_barrier(O1_to, O2_count, O3); // store check on O1[0..O2]
|
||||
|
||||
__ bind(done);
|
||||
__ BIND(done);
|
||||
inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);
|
||||
__ retl();
|
||||
__ delayed()->nop(); // return value in 00
|
||||
@ -2940,16 +2846,16 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_cmpxchg_ptr_entry = StubRoutines::_atomic_cmpxchg_entry;
|
||||
StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
|
||||
StubRoutines::_atomic_add_ptr_entry = StubRoutines::_atomic_add_entry;
|
||||
StubRoutines::_fence_entry = generate_fence();
|
||||
#endif // COMPILER2 !=> _LP64
|
||||
|
||||
StubRoutines::Sparc::_partial_subtype_check = generate_partial_subtype_check();
|
||||
}
|
||||
|
||||
|
||||
void generate_all() {
|
||||
// Generates all stubs and initializes the entry points
|
||||
|
||||
// Generate partial_subtype_check first here since its code depends on
|
||||
// UseZeroBaseCompressedOops which is defined after heap initialization.
|
||||
StubRoutines::Sparc::_partial_subtype_check = generate_partial_subtype_check();
|
||||
// These entry points require SharedInfo::stack0 to be set up in non-core builds
|
||||
StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError), false);
|
||||
StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false);
|
||||
|
@ -1545,7 +1545,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
|
||||
|
||||
// Handle all the JSR stuff here, then exit.
|
||||
// It's much shorter and cleaner than intermingling with the
|
||||
// non-JSR normal-branch stuff occuring below.
|
||||
// non-JSR normal-branch stuff occurring below.
|
||||
if( is_jsr ) {
|
||||
// compute return address as bci in Otos_i
|
||||
__ ld_ptr(Address(Lmethod, 0, in_bytes(methodOopDesc::const_offset())), G3_scratch);
|
||||
@ -3079,7 +3079,7 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
Label ok;
|
||||
|
||||
// Check that entry is non-null. Null entries are probably a bytecode
|
||||
// problem. If the interface isn't implemented by the reciever class,
|
||||
// problem. If the interface isn't implemented by the receiver class,
|
||||
// the VM should throw IncompatibleClassChangeError. linkResolver checks
|
||||
// this too but that's only if the entry isn't already resolved, so we
|
||||
// need to check again.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -62,7 +62,7 @@ void VM_Version::initialize() {
|
||||
if (is_niagara1()) {
|
||||
// Indirect branch is the same cost as direct
|
||||
if (FLAG_IS_DEFAULT(UseInlineCaches)) {
|
||||
UseInlineCaches = false;
|
||||
FLAG_SET_DEFAULT(UseInlineCaches, false);
|
||||
}
|
||||
#ifdef _LP64
|
||||
// Single issue niagara1 is slower for CompressedOops
|
||||
@ -72,33 +72,50 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_ERGO(bool, UseCompressedOops, false);
|
||||
}
|
||||
}
|
||||
// 32-bit oops don't make sense for the 64-bit VM on sparc
|
||||
// since the 32-bit VM has the same registers and smaller objects.
|
||||
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
|
||||
#endif // _LP64
|
||||
#ifdef COMPILER2
|
||||
// Indirect branch is the same cost as direct
|
||||
if (FLAG_IS_DEFAULT(UseJumpTables)) {
|
||||
UseJumpTables = true;
|
||||
FLAG_SET_DEFAULT(UseJumpTables, true);
|
||||
}
|
||||
// Single-issue, so entry and loop tops are
|
||||
// aligned on a single instruction boundary
|
||||
if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
|
||||
InteriorEntryAlignment = 4;
|
||||
FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
|
||||
OptoLoopAlignment = 4;
|
||||
FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
|
||||
}
|
||||
if (is_niagara1_plus() && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
|
||||
// Use smaller prefetch distance on N2
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use hardware population count instruction if available.
|
||||
if (has_hardware_popc()) {
|
||||
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
|
||||
FLAG_SET_DEFAULT(UsePopCountInstruction, true);
|
||||
}
|
||||
}
|
||||
|
||||
char buf[512];
|
||||
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
|
||||
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
(has_v8() ? ", has_v8" : ""),
|
||||
(has_v9() ? ", has_v9" : ""),
|
||||
(has_hardware_popc() ? ", popc" : ""),
|
||||
(has_vis1() ? ", has_vis1" : ""),
|
||||
(has_vis2() ? ", has_vis2" : ""),
|
||||
(is_ultra3() ? ", is_ultra3" : ""),
|
||||
(is_sun4v() ? ", is_sun4v" : ""),
|
||||
(is_niagara1() ? ", is_niagara1" : ""),
|
||||
(!has_hardware_int_muldiv() ? ", no-muldiv" : ""),
|
||||
(is_niagara1_plus() ? ", is_niagara1_plus" : ""),
|
||||
(!has_hardware_mul32() ? ", no-mul32" : ""),
|
||||
(!has_hardware_div32() ? ", no-div32" : ""),
|
||||
(!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
|
||||
|
||||
// buf is started with ", " or is empty
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -26,12 +26,14 @@ class VM_Version: public Abstract_VM_Version {
|
||||
protected:
|
||||
enum Feature_Flag {
|
||||
v8_instructions = 0,
|
||||
hardware_int_muldiv = 1,
|
||||
hardware_fsmuld = 2,
|
||||
v9_instructions = 3,
|
||||
vis1_instructions = 4,
|
||||
vis2_instructions = 5,
|
||||
sun4v_instructions = 6
|
||||
hardware_mul32 = 1,
|
||||
hardware_div32 = 2,
|
||||
hardware_fsmuld = 3,
|
||||
hardware_popc = 4,
|
||||
v9_instructions = 5,
|
||||
vis1_instructions = 6,
|
||||
vis2_instructions = 7,
|
||||
sun4v_instructions = 8
|
||||
};
|
||||
|
||||
enum Feature_Flag_Set {
|
||||
@ -39,16 +41,18 @@ protected:
|
||||
all_features_m = -1,
|
||||
|
||||
v8_instructions_m = 1 << v8_instructions,
|
||||
hardware_int_muldiv_m = 1 << hardware_int_muldiv,
|
||||
hardware_mul32_m = 1 << hardware_mul32,
|
||||
hardware_div32_m = 1 << hardware_div32,
|
||||
hardware_fsmuld_m = 1 << hardware_fsmuld,
|
||||
hardware_popc_m = 1 << hardware_popc,
|
||||
v9_instructions_m = 1 << v9_instructions,
|
||||
vis1_instructions_m = 1 << vis1_instructions,
|
||||
vis2_instructions_m = 1 << vis2_instructions,
|
||||
sun4v_m = 1 << sun4v_instructions,
|
||||
|
||||
generic_v8_m = v8_instructions_m | hardware_int_muldiv_m | hardware_fsmuld_m,
|
||||
generic_v9_m = generic_v8_m | v9_instructions_m | vis1_instructions_m,
|
||||
ultra3_m = generic_v9_m | vis2_instructions_m,
|
||||
generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
|
||||
generic_v9_m = generic_v8_m | v9_instructions_m,
|
||||
ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m,
|
||||
|
||||
// Temporary until we have something more accurate
|
||||
niagara1_unique_m = sun4v_m,
|
||||
@ -62,7 +66,7 @@ protected:
|
||||
static int determine_features();
|
||||
static int platform_features(int features);
|
||||
|
||||
static bool is_niagara1(int features) { return (features & niagara1_m) == niagara1_m; }
|
||||
static bool is_niagara1(int features) { return (features & sun4v_m) != 0; }
|
||||
|
||||
static int maximum_niagara1_processor_count() { return 32; }
|
||||
// Returns true if the platform is in the niagara line and
|
||||
@ -76,8 +80,10 @@ public:
|
||||
// Instruction support
|
||||
static bool has_v8() { return (_features & v8_instructions_m) != 0; }
|
||||
static bool has_v9() { return (_features & v9_instructions_m) != 0; }
|
||||
static bool has_hardware_int_muldiv() { return (_features & hardware_int_muldiv_m) != 0; }
|
||||
static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; }
|
||||
static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; }
|
||||
static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
|
||||
static bool has_hardware_popc() { return (_features & hardware_popc_m) != 0; }
|
||||
static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
|
||||
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
|
||||
|
||||
|
@ -106,6 +106,15 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
|
||||
__ delayed()->nop();
|
||||
|
||||
masm->flush();
|
||||
|
||||
if (PrintMiscellaneous && (WizardMode || Verbose)) {
|
||||
tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
|
||||
vtable_index, s->entry_point(),
|
||||
(int)(s->code_end() - s->entry_point()),
|
||||
(int)(s->code_end() - __ pc()));
|
||||
}
|
||||
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
|
||||
|
||||
s->set_exception_points(npe_addr, ame_addr);
|
||||
return s;
|
||||
}
|
||||
@ -113,9 +122,9 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
|
||||
|
||||
// NOTE: %%%% if any change is made to this stub make sure that the function
|
||||
// pd_code_size_limit is changed to ensure the correct size for VtableStub
|
||||
VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
|
||||
VtableStub* VtableStubs::create_itable_stub(int itable_index) {
|
||||
const int sparc_code_length = VtableStub::pd_code_size_limit(false);
|
||||
VtableStub* s = new(sparc_code_length) VtableStub(false, vtable_index);
|
||||
VtableStub* s = new(sparc_code_length) VtableStub(false, itable_index);
|
||||
ResourceMark rm;
|
||||
CodeBuffer cb(s->entry_point(), sparc_code_length);
|
||||
MacroAssembler* masm = new MacroAssembler(&cb);
|
||||
@ -139,7 +148,6 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
|
||||
// are passed in the %o registers. Instead, longs are passed in G1 and G4
|
||||
// and so those registers are not available here.
|
||||
__ save(SP,-frame::register_save_words*wordSize,SP);
|
||||
Register I0_receiver = I0; // Location of receiver after save
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (CountCompiledCalls) {
|
||||
@ -151,63 +159,31 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
|
||||
}
|
||||
#endif /* PRODUCT */
|
||||
|
||||
// load start of itable entries into L0 register
|
||||
const int base = instanceKlass::vtable_start_offset() * wordSize;
|
||||
__ ld(Address(G3_klassOop, 0, instanceKlass::vtable_length_offset() * wordSize), L0);
|
||||
|
||||
// %%% Could store the aligned, prescaled offset in the klassoop.
|
||||
__ sll(L0, exact_log2(vtableEntry::size() * wordSize), L0);
|
||||
// see code for instanceKlass::start_of_itable!
|
||||
const int vtable_alignment = align_object_offset(1);
|
||||
assert(vtable_alignment == 1 || vtable_alignment == 2, "");
|
||||
const int odd_bit = vtableEntry::size() * wordSize;
|
||||
if (vtable_alignment == 2) {
|
||||
__ and3(L0, odd_bit, L1); // isolate the odd bit
|
||||
}
|
||||
__ add(G3_klassOop, L0, L0);
|
||||
if (vtable_alignment == 2) {
|
||||
__ add(L0, L1, L0); // double the odd bit, to align up
|
||||
}
|
||||
|
||||
// Loop over all itable entries until desired interfaceOop (G5_interface) found
|
||||
__ bind(search);
|
||||
|
||||
// %%%% Could load both offset and interface in one ldx, if they were
|
||||
// in the opposite order. This would save a load.
|
||||
__ ld_ptr(L0, base + itableOffsetEntry::interface_offset_in_bytes(), L1);
|
||||
|
||||
// If the entry is NULL then we've reached the end of the table
|
||||
// without finding the expected interface, so throw an exception
|
||||
Label throw_icce;
|
||||
__ bpr(Assembler::rc_z, false, Assembler::pn, L1, throw_icce);
|
||||
__ delayed()->cmp(G5_interface, L1);
|
||||
__ brx(Assembler::notEqual, true, Assembler::pn, search);
|
||||
__ delayed()->add(L0, itableOffsetEntry::size() * wordSize, L0);
|
||||
|
||||
// entry found and L0 points to it, move offset of vtable for interface into L0
|
||||
__ ld(L0, base + itableOffsetEntry::offset_offset_in_bytes(), L0);
|
||||
|
||||
// Compute itableMethodEntry and get methodOop(G5_method) and entrypoint(L0) for compiler
|
||||
const int method_offset = (itableMethodEntry::size() * wordSize * vtable_index) + itableMethodEntry::method_offset_in_bytes();
|
||||
__ add(G3_klassOop, L0, L1);
|
||||
__ ld_ptr(L1, method_offset, G5_method);
|
||||
Register L5_method = L5;
|
||||
__ lookup_interface_method(// inputs: rec. class, interface, itable index
|
||||
G3_klassOop, G5_interface, itable_index,
|
||||
// outputs: method, scan temp. reg
|
||||
L5_method, L2, L3,
|
||||
throw_icce);
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (DebugVtables) {
|
||||
Label L01;
|
||||
__ ld_ptr(L1, method_offset, G5_method);
|
||||
__ bpr(Assembler::rc_nz, false, Assembler::pt, G5_method, L01);
|
||||
__ bpr(Assembler::rc_nz, false, Assembler::pt, L5_method, L01);
|
||||
__ delayed()->nop();
|
||||
__ stop("methodOop is null");
|
||||
__ bind(L01);
|
||||
__ verify_oop(G5_method);
|
||||
__ verify_oop(L5_method);
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the following load is through a NULL pointer, we'll take an OS
|
||||
// exception that should translate into an AbstractMethodError. We need the
|
||||
// window count to be correct at that time.
|
||||
__ restore(); // Restore registers BEFORE the AME point
|
||||
__ restore(L5_method, 0, G5_method);
|
||||
// Restore registers *before* the AME point.
|
||||
|
||||
address ame_addr = __ pc(); // if the vtable entry is null, the method is abstract
|
||||
__ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch);
|
||||
@ -225,6 +201,12 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
|
||||
|
||||
masm->flush();
|
||||
|
||||
if (PrintMiscellaneous && (WizardMode || Verbose)) {
|
||||
tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
|
||||
itable_index, s->entry_point(),
|
||||
(int)(s->code_end() - s->entry_point()),
|
||||
(int)(s->code_end() - __ pc()));
|
||||
}
|
||||
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
|
||||
|
||||
s->set_exception_points(npe_addr, ame_addr);
|
||||
@ -239,14 +221,15 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
|
||||
if (is_vtable_stub) {
|
||||
// ld;ld;ld,jmp,nop
|
||||
const int basic = 5*BytesPerInstWord +
|
||||
// shift;add for load_klass
|
||||
(UseCompressedOops ? 2*BytesPerInstWord : 0);
|
||||
// shift;add for load_klass (only shift with zero heap based)
|
||||
(UseCompressedOops ?
|
||||
((Universe::narrow_oop_base() == NULL) ? BytesPerInstWord : 2*BytesPerInstWord) : 0);
|
||||
return basic + slop;
|
||||
} else {
|
||||
// save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore, sethi, jmpl, restore
|
||||
const int basic = (20 LP64_ONLY(+ 6)) * BytesPerInstWord +
|
||||
// shift;add for load_klass
|
||||
(UseCompressedOops ? 2*BytesPerInstWord : 0);
|
||||
const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
|
||||
// shift;add for load_klass (only shift with zero heap based)
|
||||
(UseCompressedOops ?
|
||||
((Universe::narrow_oop_base() == NULL) ? BytesPerInstWord : 2*BytesPerInstWord) : 0);
|
||||
return (basic + slop);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -129,13 +129,19 @@ Address::Address(address loc, RelocationHolder spec) {
|
||||
// Convert the raw encoding form into the form expected by the constructor for
|
||||
// Address. An index of 4 (rsp) corresponds to having no index, so convert
|
||||
// that to noreg for the Address constructor.
|
||||
Address Address::make_raw(int base, int index, int scale, int disp) {
|
||||
Address Address::make_raw(int base, int index, int scale, int disp, bool disp_is_oop) {
|
||||
RelocationHolder rspec;
|
||||
if (disp_is_oop) {
|
||||
rspec = Relocation::spec_simple(relocInfo::oop_type);
|
||||
}
|
||||
bool valid_index = index != rsp->encoding();
|
||||
if (valid_index) {
|
||||
Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp));
|
||||
madr._rspec = rspec;
|
||||
return madr;
|
||||
} else {
|
||||
Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp));
|
||||
madr._rspec = rspec;
|
||||
return madr;
|
||||
}
|
||||
}
|
||||
@ -721,7 +727,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
|
||||
}
|
||||
|
||||
#ifdef _LP64
|
||||
assert(false, "fix locate_operand");
|
||||
assert(which == narrow_oop_operand && !is_64bit, "instruction is not a movl adr, imm32");
|
||||
#else
|
||||
assert(which == imm_operand, "instruction has only an imm field");
|
||||
#endif // LP64
|
||||
@ -1432,26 +1438,12 @@ void Assembler::lock() {
|
||||
}
|
||||
}
|
||||
|
||||
// Serializes memory.
|
||||
// Emit mfence instruction
|
||||
void Assembler::mfence() {
|
||||
// Memory barriers are only needed on multiprocessors
|
||||
if (os::is_MP()) {
|
||||
if( LP64_ONLY(true ||) VM_Version::supports_sse2() ) {
|
||||
emit_byte( 0x0F ); // MFENCE; faster blows no regs
|
||||
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
|
||||
emit_byte( 0x0F );
|
||||
emit_byte( 0xAE );
|
||||
emit_byte( 0xF0 );
|
||||
} else {
|
||||
// All usable chips support "locked" instructions which suffice
|
||||
// as barriers, and are much faster than the alternative of
|
||||
// using cpuid instruction. We use here a locked add [esp],0.
|
||||
// This is conveniently otherwise a no-op except for blowing
|
||||
// flags (which we save and restore.)
|
||||
pushf(); // Save eflags register
|
||||
lock();
|
||||
addl(Address(rsp, 0), 0);// Assert the lock# signal here
|
||||
popf(); // Restore eflags register
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::mov(Register dst, Register src) {
|
||||
@ -2181,12 +2173,56 @@ void Assembler::orl(Register dst, Register src) {
|
||||
emit_arith(0x0B, 0xC0, dst, src);
|
||||
}
|
||||
|
||||
void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
|
||||
assert(VM_Version::supports_sse4_2(), "");
|
||||
|
||||
InstructionMark im(this);
|
||||
emit_byte(0x66);
|
||||
prefix(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0x3A);
|
||||
emit_byte(0x61);
|
||||
emit_operand(dst, src);
|
||||
emit_byte(imm8);
|
||||
}
|
||||
|
||||
void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
|
||||
assert(VM_Version::supports_sse4_2(), "");
|
||||
|
||||
emit_byte(0x66);
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0x3A);
|
||||
emit_byte(0x61);
|
||||
emit_byte(0xC0 | encode);
|
||||
emit_byte(imm8);
|
||||
}
|
||||
|
||||
// generic
|
||||
void Assembler::pop(Register dst) {
|
||||
int encode = prefix_and_encode(dst->encoding());
|
||||
emit_byte(0x58 | encode);
|
||||
}
|
||||
|
||||
void Assembler::popcntl(Register dst, Address src) {
|
||||
assert(VM_Version::supports_popcnt(), "must support");
|
||||
InstructionMark im(this);
|
||||
emit_byte(0xF3);
|
||||
prefix(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB8);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::popcntl(Register dst, Register src) {
|
||||
assert(VM_Version::supports_popcnt(), "must support");
|
||||
emit_byte(0xF3);
|
||||
int encode = prefix_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB8);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::popf() {
|
||||
emit_byte(0x9D);
|
||||
}
|
||||
@ -2319,6 +2355,29 @@ void Assembler::psrlq(XMMRegister dst, int shift) {
|
||||
emit_byte(shift);
|
||||
}
|
||||
|
||||
void Assembler::ptest(XMMRegister dst, Address src) {
|
||||
assert(VM_Version::supports_sse4_1(), "");
|
||||
|
||||
InstructionMark im(this);
|
||||
emit_byte(0x66);
|
||||
prefix(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0x38);
|
||||
emit_byte(0x17);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
|
||||
assert(VM_Version::supports_sse4_1(), "");
|
||||
|
||||
emit_byte(0x66);
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0x38);
|
||||
emit_byte(0x17);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
|
||||
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
|
||||
emit_byte(0x66);
|
||||
@ -3218,12 +3277,6 @@ void Assembler::fyl2x() {
|
||||
emit_byte(0xF1);
|
||||
}
|
||||
|
||||
void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format) {
|
||||
InstructionMark im(this);
|
||||
int encode = prefix_and_encode(dst->encoding());
|
||||
emit_byte(0xB8 | encode);
|
||||
emit_data((int)imm32, rspec, format);
|
||||
}
|
||||
|
||||
#ifndef _LP64
|
||||
|
||||
@ -3243,6 +3296,12 @@ void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder cons
|
||||
emit_data((int)imm32, rspec, 0);
|
||||
}
|
||||
|
||||
void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) {
|
||||
InstructionMark im(this);
|
||||
int encode = prefix_and_encode(dst->encoding());
|
||||
emit_byte(0xB8 | encode);
|
||||
emit_data((int)imm32, rspec, 0);
|
||||
}
|
||||
|
||||
void Assembler::popa() { // 32bit
|
||||
emit_byte(0x61);
|
||||
@ -3851,6 +3910,37 @@ void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder con
|
||||
emit_data64(imm64, rspec);
|
||||
}
|
||||
|
||||
void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) {
|
||||
InstructionMark im(this);
|
||||
int encode = prefix_and_encode(dst->encoding());
|
||||
emit_byte(0xB8 | encode);
|
||||
emit_data((int)imm32, rspec, narrow_oop_operand);
|
||||
}
|
||||
|
||||
void Assembler::mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec) {
|
||||
InstructionMark im(this);
|
||||
prefix(dst);
|
||||
emit_byte(0xC7);
|
||||
emit_operand(rax, dst, 4);
|
||||
emit_data((int)imm32, rspec, narrow_oop_operand);
|
||||
}
|
||||
|
||||
void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) {
|
||||
InstructionMark im(this);
|
||||
int encode = prefix_and_encode(src1->encoding());
|
||||
emit_byte(0x81);
|
||||
emit_byte(0xF8 | encode);
|
||||
emit_data((int)imm32, rspec, narrow_oop_operand);
|
||||
}
|
||||
|
||||
void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) {
|
||||
InstructionMark im(this);
|
||||
prefix(src1);
|
||||
emit_byte(0x81);
|
||||
emit_operand(rax, src1, 4);
|
||||
emit_data((int)imm32, rspec, narrow_oop_operand);
|
||||
}
|
||||
|
||||
void Assembler::movdq(XMMRegister dst, Register src) {
|
||||
// table D-1 says MMX/SSE2
|
||||
NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), ""));
|
||||
@ -3892,6 +3982,21 @@ void Assembler::movq(Address dst, Register src) {
|
||||
emit_operand(src, dst);
|
||||
}
|
||||
|
||||
void Assembler::movsbq(Register dst, Address src) {
|
||||
InstructionMark im(this);
|
||||
prefixq(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBE);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::movsbq(Register dst, Register src) {
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBE);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::movslq(Register dst, int32_t imm32) {
|
||||
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
|
||||
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
|
||||
@ -3925,6 +4030,51 @@ void Assembler::movslq(Register dst, Register src) {
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::movswq(Register dst, Address src) {
|
||||
InstructionMark im(this);
|
||||
prefixq(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBF);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::movswq(Register dst, Register src) {
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBF);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::movzbq(Register dst, Address src) {
|
||||
InstructionMark im(this);
|
||||
prefixq(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB6);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::movzbq(Register dst, Register src) {
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB6);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::movzwq(Register dst, Address src) {
|
||||
InstructionMark im(this);
|
||||
prefixq(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB7);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::movzwq(Register dst, Register src) {
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB7);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::negq(Register dst) {
|
||||
int encode = prefixq_and_encode(dst->encoding());
|
||||
emit_byte(0xF7);
|
||||
@ -3983,6 +4133,25 @@ void Assembler::popa() { // 64bit
|
||||
addq(rsp, 16 * wordSize);
|
||||
}
|
||||
|
||||
void Assembler::popcntq(Register dst, Address src) {
|
||||
assert(VM_Version::supports_popcnt(), "must support");
|
||||
InstructionMark im(this);
|
||||
emit_byte(0xF3);
|
||||
prefixq(src, dst);
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB8);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::popcntq(Register dst, Register src) {
|
||||
assert(VM_Version::supports_popcnt(), "must support");
|
||||
emit_byte(0xF3);
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xB8);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::popq(Address dst) {
|
||||
InstructionMark im(this);
|
||||
prefixq(dst);
|
||||
@ -6197,8 +6366,11 @@ int MacroAssembler::load_signed_byte(Register dst, Address src) {
|
||||
return off;
|
||||
}
|
||||
|
||||
// word => int32 which seems bad for 64bit
|
||||
int MacroAssembler::load_signed_word(Register dst, Address src) {
|
||||
// Note: load_signed_short used to be called load_signed_word.
|
||||
// Although the 'w' in x86 opcodes refers to the term "word" in the assembler
|
||||
// manual, which means 16 bits, that usage is found nowhere in HotSpot code.
|
||||
// The term "word" in HotSpot means a 32- or 64-bit machine word.
|
||||
int MacroAssembler::load_signed_short(Register dst, Address src) {
|
||||
int off;
|
||||
if (LP64_ONLY(true ||) VM_Version::is_P6()) {
|
||||
// This is dubious to me since it seems safe to do a signed 16 => 64 bit
|
||||
@ -6207,7 +6379,7 @@ int MacroAssembler::load_signed_word(Register dst, Address src) {
|
||||
off = offset();
|
||||
movswl(dst, src); // movsxw
|
||||
} else {
|
||||
off = load_unsigned_word(dst, src);
|
||||
off = load_unsigned_short(dst, src);
|
||||
shll(dst, 16);
|
||||
sarl(dst, 16);
|
||||
}
|
||||
@ -6229,7 +6401,8 @@ int MacroAssembler::load_unsigned_byte(Register dst, Address src) {
|
||||
return off;
|
||||
}
|
||||
|
||||
int MacroAssembler::load_unsigned_word(Register dst, Address src) {
|
||||
// Note: load_unsigned_short used to be called load_unsigned_word.
|
||||
int MacroAssembler::load_unsigned_short(Register dst, Address src) {
|
||||
// According to Intel Doc. AP-526, "Zero-Extension of Short", p.16,
|
||||
// and "3.9 Partial Register Penalties", p. 22).
|
||||
int off;
|
||||
@ -6244,6 +6417,28 @@ int MacroAssembler::load_unsigned_word(Register dst, Address src) {
|
||||
return off;
|
||||
}
|
||||
|
||||
void MacroAssembler::load_sized_value(Register dst, Address src,
|
||||
int size_in_bytes, bool is_signed) {
|
||||
switch (size_in_bytes ^ (is_signed ? -1 : 0)) {
|
||||
#ifndef _LP64
|
||||
// For case 8, caller is responsible for manually loading
|
||||
// the second word into another register.
|
||||
case ~8: // fall through:
|
||||
case 8: movl( dst, src ); break;
|
||||
#else
|
||||
case ~8: // fall through:
|
||||
case 8: movq( dst, src ); break;
|
||||
#endif
|
||||
case ~4: // fall through:
|
||||
case 4: movl( dst, src ); break;
|
||||
case ~2: load_signed_short( dst, src ); break;
|
||||
case 2: load_unsigned_short( dst, src ); break;
|
||||
case ~1: load_signed_byte( dst, src ); break;
|
||||
case 1: load_unsigned_byte( dst, src ); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::mov32(AddressLiteral dst, Register src) {
|
||||
if (reachable(dst)) {
|
||||
movl(as_Address(dst), src);
|
||||
@ -6463,7 +6658,8 @@ void MacroAssembler::serialize_memory(Register thread, Register tmp) {
|
||||
Address index(noreg, tmp, Address::times_1);
|
||||
ExternalAddress page(os::get_memory_serialize_page());
|
||||
|
||||
movptr(ArrayAddress(page, index), tmp);
|
||||
// Size of store must match masking code above
|
||||
movl(as_Address(ArrayAddress(page, index)), tmp);
|
||||
}
|
||||
|
||||
// Calls to C land
|
||||
@ -7049,6 +7245,300 @@ void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) {
|
||||
}
|
||||
|
||||
|
||||
// Look up the method for a megamorphic invokeinterface call.
|
||||
// The target method is determined by <intf_klass, itable_index>.
|
||||
// The receiver klass is in recv_klass.
|
||||
// On success, the result will be in method_result, and execution falls through.
|
||||
// On failure, execution transfers to the given label.
|
||||
void MacroAssembler::lookup_interface_method(Register recv_klass,
|
||||
Register intf_klass,
|
||||
RegisterOrConstant itable_index,
|
||||
Register method_result,
|
||||
Register scan_temp,
|
||||
Label& L_no_such_interface) {
|
||||
assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
|
||||
assert(itable_index.is_constant() || itable_index.as_register() == method_result,
|
||||
"caller must use same register for non-constant itable index as for method");
|
||||
|
||||
// Compute start of first itableOffsetEntry (which is at the end of the vtable)
|
||||
int vtable_base = instanceKlass::vtable_start_offset() * wordSize;
|
||||
int itentry_off = itableMethodEntry::method_offset_in_bytes();
|
||||
int scan_step = itableOffsetEntry::size() * wordSize;
|
||||
int vte_size = vtableEntry::size() * wordSize;
|
||||
Address::ScaleFactor times_vte_scale = Address::times_ptr;
|
||||
assert(vte_size == wordSize, "else adjust times_vte_scale");
|
||||
|
||||
movl(scan_temp, Address(recv_klass, instanceKlass::vtable_length_offset() * wordSize));
|
||||
|
||||
// %%% Could store the aligned, prescaled offset in the klassoop.
|
||||
lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
|
||||
if (HeapWordsPerLong > 1) {
|
||||
// Round up to align_object_offset boundary
|
||||
// see code for instanceKlass::start_of_itable!
|
||||
round_to(scan_temp, BytesPerLong);
|
||||
}
|
||||
|
||||
// Adjust recv_klass by scaled itable_index, so we can free itable_index.
|
||||
assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
|
||||
lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
|
||||
|
||||
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
|
||||
// if (scan->interface() == intf) {
|
||||
// result = (klass + scan->offset() + itable_index);
|
||||
// }
|
||||
// }
|
||||
Label search, found_method;
|
||||
|
||||
for (int peel = 1; peel >= 0; peel--) {
|
||||
movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
|
||||
cmpptr(intf_klass, method_result);
|
||||
|
||||
if (peel) {
|
||||
jccb(Assembler::equal, found_method);
|
||||
} else {
|
||||
jccb(Assembler::notEqual, search);
|
||||
// (invert the test to fall through to found_method...)
|
||||
}
|
||||
|
||||
if (!peel) break;
|
||||
|
||||
bind(search);
|
||||
|
||||
// Check that the previous entry is non-null. A null entry means that
|
||||
// the receiver class doesn't implement the interface, and wasn't the
|
||||
// same as when the caller was compiled.
|
||||
testptr(method_result, method_result);
|
||||
jcc(Assembler::zero, L_no_such_interface);
|
||||
addptr(scan_temp, scan_step);
|
||||
}
|
||||
|
||||
bind(found_method);
|
||||
|
||||
// Got a hit.
|
||||
movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
|
||||
movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::check_klass_subtype(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Label& L_success) {
|
||||
Label L_failure;
|
||||
check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, &L_success, &L_failure, NULL);
|
||||
check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, noreg, &L_success, NULL);
|
||||
bind(L_failure);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure,
|
||||
Label* L_slow_path,
|
||||
RegisterOrConstant super_check_offset) {
|
||||
assert_different_registers(sub_klass, super_klass, temp_reg);
|
||||
bool must_load_sco = (super_check_offset.constant_or_zero() == -1);
|
||||
if (super_check_offset.is_register()) {
|
||||
assert_different_registers(sub_klass, super_klass,
|
||||
super_check_offset.as_register());
|
||||
} else if (must_load_sco) {
|
||||
assert(temp_reg != noreg, "supply either a temp or a register offset");
|
||||
}
|
||||
|
||||
Label L_fallthrough;
|
||||
int label_nulls = 0;
|
||||
if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
|
||||
if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
|
||||
if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; }
|
||||
assert(label_nulls <= 1, "at most one NULL in the batch");
|
||||
|
||||
int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_super_cache_offset_in_bytes());
|
||||
int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::super_check_offset_offset_in_bytes());
|
||||
Address super_check_offset_addr(super_klass, sco_offset);
|
||||
|
||||
// Hacked jcc, which "knows" that L_fallthrough, at least, is in
|
||||
// range of a jccb. If this routine grows larger, reconsider at
|
||||
// least some of these.
|
||||
#define local_jcc(assembler_cond, label) \
|
||||
if (&(label) == &L_fallthrough) jccb(assembler_cond, label); \
|
||||
else jcc( assembler_cond, label) /*omit semi*/
|
||||
|
||||
// Hacked jmp, which may only be used just before L_fallthrough.
|
||||
#define final_jmp(label) \
|
||||
if (&(label) == &L_fallthrough) { /*do nothing*/ } \
|
||||
else jmp(label) /*omit semi*/
|
||||
|
||||
// If the pointers are equal, we are done (e.g., String[] elements).
|
||||
// This self-check enables sharing of secondary supertype arrays among
|
||||
// non-primary types such as array-of-interface. Otherwise, each such
|
||||
// type would need its own customized SSA.
|
||||
// We move this check to the front of the fast path because many
|
||||
// type checks are in fact trivially successful in this manner,
|
||||
// so we get a nicely predicted branch right at the start of the check.
|
||||
cmpptr(sub_klass, super_klass);
|
||||
local_jcc(Assembler::equal, *L_success);
|
||||
|
||||
// Check the supertype display:
|
||||
if (must_load_sco) {
|
||||
// Positive movl does right thing on LP64.
|
||||
movl(temp_reg, super_check_offset_addr);
|
||||
super_check_offset = RegisterOrConstant(temp_reg);
|
||||
}
|
||||
Address super_check_addr(sub_klass, super_check_offset, Address::times_1, 0);
|
||||
cmpptr(super_klass, super_check_addr); // load displayed supertype
|
||||
|
||||
// This check has worked decisively for primary supers.
|
||||
// Secondary supers are sought in the super_cache ('super_cache_addr').
|
||||
// (Secondary supers are interfaces and very deeply nested subtypes.)
|
||||
// This works in the same check above because of a tricky aliasing
|
||||
// between the super_cache and the primary super display elements.
|
||||
// (The 'super_check_addr' can address either, as the case requires.)
|
||||
// Note that the cache is updated below if it does not help us find
|
||||
// what we need immediately.
|
||||
// So if it was a primary super, we can just fail immediately.
|
||||
// Otherwise, it's the slow path for us (no success at this point).
|
||||
|
||||
if (super_check_offset.is_register()) {
|
||||
local_jcc(Assembler::equal, *L_success);
|
||||
cmpl(super_check_offset.as_register(), sc_offset);
|
||||
if (L_failure == &L_fallthrough) {
|
||||
local_jcc(Assembler::equal, *L_slow_path);
|
||||
} else {
|
||||
local_jcc(Assembler::notEqual, *L_failure);
|
||||
final_jmp(*L_slow_path);
|
||||
}
|
||||
} else if (super_check_offset.as_constant() == sc_offset) {
|
||||
// Need a slow path; fast failure is impossible.
|
||||
if (L_slow_path == &L_fallthrough) {
|
||||
local_jcc(Assembler::equal, *L_success);
|
||||
} else {
|
||||
local_jcc(Assembler::notEqual, *L_slow_path);
|
||||
final_jmp(*L_success);
|
||||
}
|
||||
} else {
|
||||
// No slow path; it's a fast decision.
|
||||
if (L_failure == &L_fallthrough) {
|
||||
local_jcc(Assembler::equal, *L_success);
|
||||
} else {
|
||||
local_jcc(Assembler::notEqual, *L_failure);
|
||||
final_jmp(*L_success);
|
||||
}
|
||||
}
|
||||
|
||||
bind(L_fallthrough);
|
||||
|
||||
#undef local_jcc
|
||||
#undef final_jmp
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure,
|
||||
bool set_cond_codes) {
|
||||
assert_different_registers(sub_klass, super_klass, temp_reg);
|
||||
if (temp2_reg != noreg)
|
||||
assert_different_registers(sub_klass, super_klass, temp_reg, temp2_reg);
|
||||
#define IS_A_TEMP(reg) ((reg) == temp_reg || (reg) == temp2_reg)
|
||||
|
||||
Label L_fallthrough;
|
||||
int label_nulls = 0;
|
||||
if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
|
||||
if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
|
||||
assert(label_nulls <= 1, "at most one NULL in the batch");
|
||||
|
||||
// a couple of useful fields in sub_klass:
|
||||
int ss_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_supers_offset_in_bytes());
|
||||
int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
|
||||
Klass::secondary_super_cache_offset_in_bytes());
|
||||
Address secondary_supers_addr(sub_klass, ss_offset);
|
||||
Address super_cache_addr( sub_klass, sc_offset);
|
||||
|
||||
// Do a linear scan of the secondary super-klass chain.
|
||||
// This code is rarely used, so simplicity is a virtue here.
|
||||
// The repne_scan instruction uses fixed registers, which we must spill.
|
||||
// Don't worry too much about pre-existing connections with the input regs.
|
||||
|
||||
assert(sub_klass != rax, "killed reg"); // killed by mov(rax, super)
|
||||
assert(sub_klass != rcx, "killed reg"); // killed by lea(rcx, &pst_counter)
|
||||
|
||||
// Get super_klass value into rax (even if it was in rdi or rcx).
|
||||
bool pushed_rax = false, pushed_rcx = false, pushed_rdi = false;
|
||||
if (super_klass != rax || UseCompressedOops) {
|
||||
if (!IS_A_TEMP(rax)) { push(rax); pushed_rax = true; }
|
||||
mov(rax, super_klass);
|
||||
}
|
||||
if (!IS_A_TEMP(rcx)) { push(rcx); pushed_rcx = true; }
|
||||
if (!IS_A_TEMP(rdi)) { push(rdi); pushed_rdi = true; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
int* pst_counter = &SharedRuntime::_partial_subtype_ctr;
|
||||
ExternalAddress pst_counter_addr((address) pst_counter);
|
||||
NOT_LP64( incrementl(pst_counter_addr) );
|
||||
LP64_ONLY( lea(rcx, pst_counter_addr) );
|
||||
LP64_ONLY( incrementl(Address(rcx, 0)) );
|
||||
#endif //PRODUCT
|
||||
|
||||
// We will consult the secondary-super array.
|
||||
movptr(rdi, secondary_supers_addr);
|
||||
// Load the array length. (Positive movl does right thing on LP64.)
|
||||
movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
|
||||
// Skip to start of data.
|
||||
addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
|
||||
// Scan RCX words at [RDI] for an occurrence of RAX.
|
||||
// Set NZ/Z based on last compare.
|
||||
#ifdef _LP64
|
||||
// This part is tricky, as values in supers array could be 32 or 64 bit wide
|
||||
// and we store values in objArrays always encoded, thus we need to encode
|
||||
// the value of rax before repne. Note that rax is dead after the repne.
|
||||
if (UseCompressedOops) {
|
||||
encode_heap_oop_not_null(rax);
|
||||
// The superclass is never null; it would be a basic system error if a null
|
||||
// pointer were to sneak in here. Note that we have already loaded the
|
||||
// Klass::super_check_offset from the super_klass in the fast path,
|
||||
// so if there is a null in that register, we are already in the afterlife.
|
||||
repne_scanl();
|
||||
} else
|
||||
#endif // _LP64
|
||||
repne_scan();
|
||||
|
||||
// Unspill the temp. registers:
|
||||
if (pushed_rdi) pop(rdi);
|
||||
if (pushed_rcx) pop(rcx);
|
||||
if (pushed_rax) pop(rax);
|
||||
|
||||
if (set_cond_codes) {
|
||||
// Special hack for the AD files: rdi is guaranteed non-zero.
|
||||
assert(!pushed_rdi, "rdi must be left non-NULL");
|
||||
// Also, the condition codes are properly set Z/NZ on succeed/failure.
|
||||
}
|
||||
|
||||
if (L_failure == &L_fallthrough)
|
||||
jccb(Assembler::notEqual, *L_failure);
|
||||
else jcc(Assembler::notEqual, *L_failure);
|
||||
|
||||
// Success. Cache the super we found and proceed in triumph.
|
||||
movptr(super_cache_addr, super_klass);
|
||||
|
||||
if (L_success != &L_fallthrough) {
|
||||
jmp(*L_success);
|
||||
}
|
||||
|
||||
#undef IS_A_TEMP
|
||||
|
||||
bind(L_fallthrough);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) {
|
||||
ucomisd(dst, as_Address(src));
|
||||
}
|
||||
@ -7094,6 +7584,31 @@ void MacroAssembler::verify_oop(Register reg, const char* s) {
|
||||
}
|
||||
|
||||
|
||||
RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
|
||||
Register tmp,
|
||||
int offset) {
|
||||
intptr_t value = *delayed_value_addr;
|
||||
if (value != 0)
|
||||
return RegisterOrConstant(value + offset);
|
||||
|
||||
// load indirectly to solve generation ordering problem
|
||||
movptr(tmp, ExternalAddress((address) delayed_value_addr));
|
||||
|
||||
#ifdef ASSERT
|
||||
Label L;
|
||||
testl(tmp, tmp);
|
||||
jccb(Assembler::notZero, L);
|
||||
hlt();
|
||||
bind(L);
|
||||
#endif
|
||||
|
||||
if (offset != 0)
|
||||
addptr(tmp, offset);
|
||||
|
||||
return RegisterOrConstant(tmp);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
|
||||
if (!VerifyOops) return;
|
||||
|
||||
@ -7517,8 +8032,15 @@ void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
void MacroAssembler::load_prototype_header(Register dst, Register src) {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert(Address::times_8 == LogMinObjAlignmentInBytes &&
|
||||
Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
|
||||
} else {
|
||||
movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -7567,11 +8089,20 @@ void MacroAssembler::store_heap_oop(Address dst, Register src) {
|
||||
// Algorithm must match oop.inline.hpp encode_heap_oop.
|
||||
void MacroAssembler::encode_heap_oop(Register r) {
|
||||
assert (UseCompressedOops, "should be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
verify_oop(r, "broken oop in encode_heap_oop");
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
shrq(r, LogMinObjAlignmentInBytes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#ifdef ASSERT
|
||||
if (CheckCompressedOops) {
|
||||
Label ok;
|
||||
push(rscratch1); // cmpptr trashes rscratch1
|
||||
cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
|
||||
cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
|
||||
jcc(Assembler::equal, ok);
|
||||
stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
|
||||
bind(ok);
|
||||
@ -7587,6 +8118,7 @@ void MacroAssembler::encode_heap_oop(Register r) {
|
||||
|
||||
void MacroAssembler::encode_heap_oop_not_null(Register r) {
|
||||
assert (UseCompressedOops, "should be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
#ifdef ASSERT
|
||||
if (CheckCompressedOops) {
|
||||
Label ok;
|
||||
@ -7597,12 +8129,18 @@ void MacroAssembler::encode_heap_oop_not_null(Register r) {
|
||||
}
|
||||
#endif
|
||||
verify_oop(r, "broken oop in encode_heap_oop_not_null");
|
||||
if (Universe::narrow_oop_base() != NULL) {
|
||||
subq(r, r12_heapbase);
|
||||
}
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
shrq(r, LogMinObjAlignmentInBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
|
||||
assert (UseCompressedOops, "should be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
#ifdef ASSERT
|
||||
if (CheckCompressedOops) {
|
||||
Label ok;
|
||||
@ -7616,18 +8154,32 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
|
||||
if (dst != src) {
|
||||
movq(dst, src);
|
||||
}
|
||||
if (Universe::narrow_oop_base() != NULL) {
|
||||
subq(dst, r12_heapbase);
|
||||
}
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
shrq(dst, LogMinObjAlignmentInBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::decode_heap_oop(Register r) {
|
||||
assert (UseCompressedOops, "should be compressed");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
shlq(r, LogMinObjAlignmentInBytes);
|
||||
}
|
||||
verify_oop(r, "broken oop in decode_heap_oop");
|
||||
return;
|
||||
}
|
||||
#ifdef ASSERT
|
||||
if (CheckCompressedOops) {
|
||||
Label ok;
|
||||
push(rscratch1);
|
||||
cmpptr(r12_heapbase,
|
||||
ExternalAddress((address)Universe::heap_base_addr()));
|
||||
ExternalAddress((address)Universe::narrow_oop_base_addr()));
|
||||
jcc(Assembler::equal, ok);
|
||||
stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
|
||||
bind(ok);
|
||||
@ -7651,32 +8203,76 @@ void MacroAssembler::decode_heap_oop(Register r) {
|
||||
|
||||
void MacroAssembler::decode_heap_oop_not_null(Register r) {
|
||||
assert (UseCompressedOops, "should only be used for compressed headers");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
// Cannot assert, unverified entry point counts instructions (see .ad file)
|
||||
// vtableStubs also counts instructions in pd_code_size_limit.
|
||||
// Also do not verify_oop as this is called by verify_oop.
|
||||
assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
shlq(r, LogMinObjAlignmentInBytes);
|
||||
}
|
||||
} else {
|
||||
assert (Address::times_8 == LogMinObjAlignmentInBytes &&
|
||||
Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
|
||||
assert (UseCompressedOops, "should only be used for compressed headers");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
// Cannot assert, unverified entry point counts instructions (see .ad file)
|
||||
// vtableStubs also counts instructions in pd_code_size_limit.
|
||||
// Also do not verify_oop as this is called by verify_oop.
|
||||
assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (Address::times_8 == LogMinObjAlignmentInBytes &&
|
||||
Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
|
||||
} else if (dst != src) {
|
||||
movq(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
|
||||
assert (UseCompressedOops, "should only be used for compressed headers");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int oop_index = oop_recorder()->find_index(obj);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
mov_literal32(dst, oop_index, rspec, narrow_oop_operand);
|
||||
mov_narrow_oop(dst, oop_index, rspec);
|
||||
}
|
||||
|
||||
void MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
|
||||
assert (UseCompressedOops, "should only be used for compressed headers");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int oop_index = oop_recorder()->find_index(obj);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
mov_narrow_oop(dst, oop_index, rspec);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) {
|
||||
assert (UseCompressedOops, "should only be used for compressed headers");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int oop_index = oop_recorder()->find_index(obj);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
Assembler::cmp_narrow_oop(dst, oop_index, rspec);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) {
|
||||
assert (UseCompressedOops, "should only be used for compressed headers");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int oop_index = oop_recorder()->find_index(obj);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
Assembler::cmp_narrow_oop(dst, oop_index, rspec);
|
||||
}
|
||||
|
||||
void MacroAssembler::reinit_heapbase() {
|
||||
if (UseCompressedOops) {
|
||||
movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
|
||||
movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
|
||||
}
|
||||
}
|
||||
#endif // _LP64
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -153,6 +153,21 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||
times_8 = 3,
|
||||
times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
|
||||
};
|
||||
static ScaleFactor times(int size) {
|
||||
assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
|
||||
if (size == 8) return times_8;
|
||||
if (size == 4) return times_4;
|
||||
if (size == 2) return times_2;
|
||||
return times_1;
|
||||
}
|
||||
static int scale_size(ScaleFactor scale) {
|
||||
assert(scale != no_scale, "");
|
||||
assert(((1 << (int)times_1) == 1 &&
|
||||
(1 << (int)times_2) == 2 &&
|
||||
(1 << (int)times_4) == 4 &&
|
||||
(1 << (int)times_8) == 8), "");
|
||||
return (1 << (int)scale);
|
||||
}
|
||||
|
||||
private:
|
||||
Register _base;
|
||||
@ -197,6 +212,22 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||
"inconsistent address");
|
||||
}
|
||||
|
||||
Address(Register base, RegisterOrConstant index, ScaleFactor scale = times_1, int disp = 0)
|
||||
: _base (base),
|
||||
_index(index.register_or_noreg()),
|
||||
_scale(scale),
|
||||
_disp (disp + (index.constant_or_zero() * scale_size(scale))) {
|
||||
if (!index.is_register()) scale = Address::no_scale;
|
||||
assert(!_index->is_valid() == (scale == Address::no_scale),
|
||||
"inconsistent address");
|
||||
}
|
||||
|
||||
Address plus_disp(int disp) const {
|
||||
Address a = (*this);
|
||||
a._disp += disp;
|
||||
return a;
|
||||
}
|
||||
|
||||
// The following two overloads are used in connection with the
|
||||
// ByteSize type (see sizes.hpp). They simplify the use of
|
||||
// ByteSize'd arguments in assembly code. Note that their equivalent
|
||||
@ -224,6 +255,17 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||
assert(!index->is_valid() == (scale == Address::no_scale),
|
||||
"inconsistent address");
|
||||
}
|
||||
|
||||
Address(Register base, RegisterOrConstant index, ScaleFactor scale, ByteSize disp)
|
||||
: _base (base),
|
||||
_index(index.register_or_noreg()),
|
||||
_scale(scale),
|
||||
_disp (in_bytes(disp) + (index.constant_or_zero() * scale_size(scale))) {
|
||||
if (!index.is_register()) scale = Address::no_scale;
|
||||
assert(!_index->is_valid() == (scale == Address::no_scale),
|
||||
"inconsistent address");
|
||||
}
|
||||
|
||||
#endif // ASSERT
|
||||
|
||||
// accessors
|
||||
@ -236,11 +278,10 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||
// Convert the raw encoding form into the form expected by the constructor for
|
||||
// Address. An index of 4 (rsp) corresponds to having no index, so convert
|
||||
// that to noreg for the Address constructor.
|
||||
static Address make_raw(int base, int index, int scale, int disp);
|
||||
static Address make_raw(int base, int index, int scale, int disp, bool disp_is_oop);
|
||||
|
||||
static Address make_array(ArrayAddress);
|
||||
|
||||
|
||||
private:
|
||||
bool base_needs_rex() const {
|
||||
return _base != noreg && _base->encoding() >= 8;
|
||||
@ -537,20 +578,25 @@ private:
|
||||
|
||||
// These are all easily abused and hence protected
|
||||
|
||||
void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format = 0);
|
||||
|
||||
// 32BIT ONLY SECTION
|
||||
#ifndef _LP64
|
||||
// Make these disappear in 64bit mode since they would never be correct
|
||||
void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
|
||||
void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
|
||||
|
||||
void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
|
||||
void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
|
||||
|
||||
void push_literal32(int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
|
||||
#else
|
||||
// 64BIT ONLY SECTION
|
||||
void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); // 64BIT ONLY
|
||||
|
||||
void cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec);
|
||||
void cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec);
|
||||
|
||||
void mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec);
|
||||
void mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec);
|
||||
#endif // _LP64
|
||||
|
||||
// These are unique in that we are ensured by the caller that the 32bit
|
||||
@ -1022,15 +1068,23 @@ private:
|
||||
LoadLoad = 1 << 0
|
||||
};
|
||||
|
||||
// Serializes memory.
|
||||
// Serializes memory and blows flags
|
||||
void membar(Membar_mask_bits order_constraint) {
|
||||
// We only have to handle StoreLoad and LoadLoad
|
||||
if (os::is_MP()) {
|
||||
// We only have to handle StoreLoad
|
||||
if (order_constraint & StoreLoad) {
|
||||
// MFENCE subsumes LFENCE
|
||||
mfence();
|
||||
} /* [jk] not needed currently: else if (order_constraint & LoadLoad) {
|
||||
lfence();
|
||||
} */
|
||||
// All usable chips support "locked" instructions which suffice
|
||||
// as barriers, and are much faster than the alternative of
|
||||
// using cpuid instruction. We use here a locked add [esp],0.
|
||||
// This is conveniently otherwise a no-op except for blowing
|
||||
// flags.
|
||||
// Any change to this code may need to revisit other places in
|
||||
// the code where this idiom is used, in particular the
|
||||
// orderAccess code.
|
||||
lock();
|
||||
addl(Address(rsp, 0), 0);// Assert the lock# signal here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mfence();
|
||||
@ -1097,6 +1151,9 @@ private:
|
||||
void movsbl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void movsbq(Register dst, Address src);
|
||||
void movsbq(Register dst, Register src);
|
||||
|
||||
// Move signed 32bit immediate to 64bit extending sign
|
||||
void movslq(Address dst, int32_t imm64);
|
||||
void movslq(Register dst, int32_t imm64);
|
||||
@ -1109,6 +1166,11 @@ private:
|
||||
void movswl(Register dst, Address src);
|
||||
void movswl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void movswq(Register dst, Address src);
|
||||
void movswq(Register dst, Register src);
|
||||
#endif
|
||||
|
||||
void movw(Address dst, int imm16);
|
||||
void movw(Register dst, Address src);
|
||||
void movw(Address dst, Register src);
|
||||
@ -1116,9 +1178,19 @@ private:
|
||||
void movzbl(Register dst, Address src);
|
||||
void movzbl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void movzbq(Register dst, Address src);
|
||||
void movzbq(Register dst, Register src);
|
||||
#endif
|
||||
|
||||
void movzwl(Register dst, Address src);
|
||||
void movzwl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void movzwq(Register dst, Address src);
|
||||
void movzwq(Register dst, Register src);
|
||||
#endif
|
||||
|
||||
void mull(Address src);
|
||||
void mull(Register src);
|
||||
|
||||
@ -1154,12 +1226,24 @@ private:
|
||||
void orq(Register dst, Address src);
|
||||
void orq(Register dst, Register src);
|
||||
|
||||
// SSE4.2 string instructions
|
||||
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
|
||||
void pcmpestri(XMMRegister xmm1, Address src, int imm8);
|
||||
|
||||
void popl(Address dst);
|
||||
|
||||
#ifdef _LP64
|
||||
void popq(Address dst);
|
||||
#endif
|
||||
|
||||
void popcntl(Register dst, Address src);
|
||||
void popcntl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void popcntq(Register dst, Address src);
|
||||
void popcntq(Register dst, Register src);
|
||||
#endif
|
||||
|
||||
// Prefetches (SSE, SSE2, 3DNOW only)
|
||||
|
||||
void prefetchnta(Address src);
|
||||
@ -1180,6 +1264,10 @@ private:
|
||||
// Shift Right Logical Quadword Immediate
|
||||
void psrlq(XMMRegister dst, int shift);
|
||||
|
||||
// Logical Compare Double Quadword
|
||||
void ptest(XMMRegister dst, XMMRegister src);
|
||||
void ptest(XMMRegister dst, Address src);
|
||||
|
||||
// Interleave Low Bytes
|
||||
void punpcklbw(XMMRegister dst, XMMRegister src);
|
||||
|
||||
@ -1393,17 +1481,20 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
// The following 4 methods return the offset of the appropriate move instruction
|
||||
|
||||
// Support for fast byte/word loading with zero extension (depending on particular CPU)
|
||||
// Support for fast byte/short loading with zero extension (depending on particular CPU)
|
||||
int load_unsigned_byte(Register dst, Address src);
|
||||
int load_unsigned_word(Register dst, Address src);
|
||||
int load_unsigned_short(Register dst, Address src);
|
||||
|
||||
// Support for fast byte/word loading with sign extension (depending on particular CPU)
|
||||
// Support for fast byte/short loading with sign extension (depending on particular CPU)
|
||||
int load_signed_byte(Register dst, Address src);
|
||||
int load_signed_word(Register dst, Address src);
|
||||
int load_signed_short(Register dst, Address src);
|
||||
|
||||
// Support for sign-extension (hi:lo = extend_sign(lo))
|
||||
void extend_sign(Register hi, Register lo);
|
||||
|
||||
// Loading values by size and signed-ness
|
||||
void load_sized_value(Register dst, Address src, int size_in_bytes, bool is_signed);
|
||||
|
||||
// Support for inc/dec with optimal instruction selection depending on value
|
||||
|
||||
void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; }
|
||||
@ -1585,6 +1676,9 @@ class MacroAssembler: public Assembler {
|
||||
void decode_heap_oop_not_null(Register dst, Register src);
|
||||
|
||||
void set_narrow_oop(Register dst, jobject obj);
|
||||
void set_narrow_oop(Address dst, jobject obj);
|
||||
void cmp_narrow_oop(Register dst, jobject obj);
|
||||
void cmp_narrow_oop(Address dst, jobject obj);
|
||||
|
||||
// if heap base register is used - reinit it with the correct value
|
||||
void reinit_heapbase();
|
||||
@ -1721,6 +1815,48 @@ class MacroAssembler: public Assembler {
|
||||
);
|
||||
void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
|
||||
|
||||
// interface method calling
|
||||
void lookup_interface_method(Register recv_klass,
|
||||
Register intf_klass,
|
||||
RegisterOrConstant itable_index,
|
||||
Register method_result,
|
||||
Register scan_temp,
|
||||
Label& no_such_interface);
|
||||
|
||||
// Test sub_klass against super_klass, with fast and slow paths.
|
||||
|
||||
// The fast path produces a tri-state answer: yes / no / maybe-slow.
|
||||
// One of the three labels can be NULL, meaning take the fall-through.
|
||||
// If super_check_offset is -1, the value is loaded up from super_klass.
|
||||
// No registers are killed, except temp_reg.
|
||||
void check_klass_subtype_fast_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure,
|
||||
Label* L_slow_path,
|
||||
RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
|
||||
|
||||
// The rest of the type check; must be wired to a corresponding fast path.
|
||||
// It does not repeat the fast path logic, so don't use it standalone.
|
||||
// The temp_reg and temp2_reg can be noreg, if no temps are available.
|
||||
// Updates the sub's secondary super cache as necessary.
|
||||
// If set_cond_codes, condition codes will be Z on success, NZ on failure.
|
||||
void check_klass_subtype_slow_path(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Register temp2_reg,
|
||||
Label* L_success,
|
||||
Label* L_failure,
|
||||
bool set_cond_codes = false);
|
||||
|
||||
// Simplified, combined version, good for typical uses.
|
||||
// Falls through on failure.
|
||||
void check_klass_subtype(Register sub_klass,
|
||||
Register super_klass,
|
||||
Register temp_reg,
|
||||
Label& L_success);
|
||||
|
||||
//----
|
||||
void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
|
||||
|
||||
@ -1763,6 +1899,10 @@ class MacroAssembler: public Assembler {
|
||||
// stack overflow + shadow pages. Also, clobbers tmp
|
||||
void bang_stack_size(Register size, Register tmp);
|
||||
|
||||
virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
|
||||
Register tmp,
|
||||
int offset);
|
||||
|
||||
// Support for serializing memory accesses between threads
|
||||
void serialize_memory(Register thread, Register tmp);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 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
|
||||
@ -554,8 +554,8 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst,
|
||||
__ jcc (Assembler::zero, noLoop);
|
||||
|
||||
// compare first characters
|
||||
__ load_unsigned_word(rcx, Address(rdi, 0));
|
||||
__ load_unsigned_word(rbx, Address(rsi, 0));
|
||||
__ load_unsigned_short(rcx, Address(rdi, 0));
|
||||
__ load_unsigned_short(rbx, Address(rsi, 0));
|
||||
__ subl(rcx, rbx);
|
||||
__ jcc(Assembler::notZero, haveResult);
|
||||
// starting loop
|
||||
@ -574,8 +574,8 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst,
|
||||
Label loop;
|
||||
__ align(wordSize);
|
||||
__ bind(loop);
|
||||
__ load_unsigned_word(rcx, Address(rdi, rax, Address::times_2, 0));
|
||||
__ load_unsigned_word(rbx, Address(rsi, rax, Address::times_2, 0));
|
||||
__ load_unsigned_short(rcx, Address(rdi, rax, Address::times_2, 0));
|
||||
__ load_unsigned_short(rbx, Address(rsi, rax, Address::times_2, 0));
|
||||
__ subl(rcx, rbx);
|
||||
__ jcc(Assembler::notZero, haveResult);
|
||||
__ increment(rax);
|
||||
@ -1598,18 +1598,9 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
|
||||
// get instance klass
|
||||
__ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
|
||||
// get super_check_offset
|
||||
__ movl(Rtmp1, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes()));
|
||||
// See if we get an immediate positive hit
|
||||
__ cmpptr(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1));
|
||||
__ jcc(Assembler::equal, done);
|
||||
// check for immediate negative hit
|
||||
__ cmpl(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ jcc(Assembler::notEqual, *stub->entry());
|
||||
// check for self
|
||||
__ cmpptr(klass_RInfo, k_RInfo);
|
||||
__ jcc(Assembler::equal, done);
|
||||
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL);
|
||||
// call out-of-line instance of __ check_klass_subtype_slow_path(...):
|
||||
__ push(klass_RInfo);
|
||||
__ push(k_RInfo);
|
||||
__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
|
||||
@ -1735,17 +1726,9 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
}
|
||||
__ bind(done);
|
||||
} else {
|
||||
__ movl(Rtmp1, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes()));
|
||||
// See if we get an immediate positive hit
|
||||
__ cmpptr(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1));
|
||||
__ jcc(Assembler::equal, done);
|
||||
// check for immediate negative hit
|
||||
__ cmpl(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ jcc(Assembler::notEqual, *stub->entry());
|
||||
// check for self
|
||||
__ cmpptr(klass_RInfo, k_RInfo);
|
||||
__ jcc(Assembler::equal, done);
|
||||
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL);
|
||||
// call out-of-line instance of __ check_klass_subtype_slow_path(...):
|
||||
__ push(klass_RInfo);
|
||||
__ push(k_RInfo);
|
||||
__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
|
||||
@ -1821,23 +1804,15 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
__ pop(dst);
|
||||
__ jmp(done);
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
{ // YUCK
|
||||
}
|
||||
else // next block is unconditional if LP64:
|
||||
#endif // LP64
|
||||
{
|
||||
assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers");
|
||||
|
||||
__ movl(dst, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes()));
|
||||
// See if we get an immediate positive hit
|
||||
__ cmpptr(k_RInfo, Address(klass_RInfo, dst, Address::times_1));
|
||||
__ jcc(Assembler::equal, one);
|
||||
// check for immediate negative hit
|
||||
__ cmpl(dst, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
__ jcc(Assembler::notEqual, zero);
|
||||
// check for self
|
||||
__ cmpptr(klass_RInfo, k_RInfo);
|
||||
__ jcc(Assembler::equal, one);
|
||||
|
||||
// perform the fast part of the checking logic
|
||||
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, dst, &one, &zero, NULL);
|
||||
// call out-of-line instance of __ check_klass_subtype_slow_path(...):
|
||||
__ push(klass_RInfo);
|
||||
__ push(k_RInfo);
|
||||
__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
|
||||
|
@ -501,7 +501,7 @@ void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {
|
||||
LIRItem right(x->y(), this);
|
||||
|
||||
left.load_item();
|
||||
// dont load constants to save register
|
||||
// don't load constants to save register
|
||||
right.load_nonconstant();
|
||||
rlock_result(x);
|
||||
arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 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
|
||||
@ -1354,6 +1354,13 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
|
||||
case slow_subtype_check_id:
|
||||
{
|
||||
// Typical calling sequence:
|
||||
// __ push(klass_RInfo); // object klass or other subclass
|
||||
// __ push(sup_k_RInfo); // array element klass or other superclass
|
||||
// __ call(slow_subtype_check);
|
||||
// Note that the subclass is pushed first, and is therefore deepest.
|
||||
// Previous versions of this code reversed the names 'sub' and 'super'.
|
||||
// This was operationally harmless but made the code unreadable.
|
||||
enum layout {
|
||||
rax_off, SLOT2(raxH_off)
|
||||
rcx_off, SLOT2(rcxH_off)
|
||||
@ -1361,9 +1368,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
rdi_off, SLOT2(rdiH_off)
|
||||
// saved_rbp_off, SLOT2(saved_rbpH_off)
|
||||
return_off, SLOT2(returnH_off)
|
||||
sub_off, SLOT2(subH_off)
|
||||
super_off, SLOT2(superH_off)
|
||||
framesize
|
||||
sup_k_off, SLOT2(sup_kH_off)
|
||||
klass_off, SLOT2(superH_off)
|
||||
framesize,
|
||||
result_off = klass_off // deepest argument is also the return value
|
||||
};
|
||||
|
||||
__ set_info("slow_subtype_check", dont_gc_arguments);
|
||||
@ -1373,19 +1381,14 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ push(rax);
|
||||
|
||||
// This is called by pushing args and not with C abi
|
||||
__ movptr(rsi, Address(rsp, (super_off) * VMRegImpl::stack_slot_size)); // super
|
||||
__ movptr(rax, Address(rsp, (sub_off ) * VMRegImpl::stack_slot_size)); // sub
|
||||
|
||||
__ movptr(rdi,Address(rsi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()));
|
||||
// since size is postive movl does right thing on 64bit
|
||||
__ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
|
||||
__ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
__ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass
|
||||
__ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass
|
||||
|
||||
Label miss;
|
||||
__ repne_scan();
|
||||
__ jcc(Assembler::notEqual, miss);
|
||||
__ movptr(Address(rsi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax);
|
||||
__ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 1); // result
|
||||
__ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss);
|
||||
|
||||
// fallthrough on success:
|
||||
__ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result
|
||||
__ pop(rax);
|
||||
__ pop(rcx);
|
||||
__ pop(rsi);
|
||||
@ -1393,7 +1396,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ ret(0);
|
||||
|
||||
__ bind(miss);
|
||||
__ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
|
||||
__ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
|
||||
__ pop(rax);
|
||||
__ pop(rcx);
|
||||
__ pop(rsi);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2007-2009 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
|
||||
@ -513,7 +513,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
// compute full expression stack limit
|
||||
|
||||
const Address size_of_stack (rbx, methodOopDesc::max_stack_offset());
|
||||
__ load_unsigned_word(rdx, size_of_stack); // get size of expression stack in words
|
||||
__ load_unsigned_short(rdx, size_of_stack); // get size of expression stack in words
|
||||
__ negptr(rdx); // so we can subtract in next step
|
||||
// Allocate expression stack
|
||||
__ lea(rsp, Address(rsp, rdx, Address::times_ptr));
|
||||
@ -523,7 +523,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
#ifdef _LP64
|
||||
// Make sure stack is properly aligned and sized for the abi
|
||||
__ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
|
||||
__ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI)
|
||||
__ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI)
|
||||
#endif // _LP64
|
||||
|
||||
|
||||
@ -659,7 +659,7 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
|
||||
// Always give one monitor to allow us to start interp if sync method.
|
||||
// Any additional monitors need a check when moving the expression stack
|
||||
const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
|
||||
__ load_unsigned_word(rax, size_of_stack); // get size of expression stack in words
|
||||
__ load_unsigned_short(rax, size_of_stack); // get size of expression stack in words
|
||||
__ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor));
|
||||
__ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
|
||||
|
||||
@ -863,13 +863,13 @@ address InterpreterGenerator::generate_accessor_entry(void) {
|
||||
__ bind(notByte);
|
||||
__ cmpl(rdx, stos);
|
||||
__ jcc(Assembler::notEqual, notShort);
|
||||
__ load_signed_word(rax, field_address);
|
||||
__ load_signed_short(rax, field_address);
|
||||
__ jmp(xreturn_path);
|
||||
|
||||
__ bind(notShort);
|
||||
__ cmpl(rdx, ctos);
|
||||
__ jcc(Assembler::notEqual, notChar);
|
||||
__ load_unsigned_word(rax, field_address);
|
||||
__ load_unsigned_short(rax, field_address);
|
||||
__ jmp(xreturn_path);
|
||||
|
||||
__ bind(notChar);
|
||||
@ -937,7 +937,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
const Register locals = rdi;
|
||||
|
||||
// get parameter size (always needed)
|
||||
__ load_unsigned_word(rcx, size_of_parameters);
|
||||
__ load_unsigned_short(rcx, size_of_parameters);
|
||||
|
||||
// rbx: methodOop
|
||||
// rcx: size of parameters
|
||||
@ -970,7 +970,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
#ifdef _LP64
|
||||
// duplicate the alignment rsp got after setting stack_base
|
||||
__ subptr(rax, frame::arg_reg_save_area_bytes); // windows
|
||||
__ andptr(rax, -16); // must be 16 byte boundry (see amd64 ABI)
|
||||
__ andptr(rax, -16); // must be 16 byte boundary (see amd64 ABI)
|
||||
#endif // _LP64
|
||||
__ cmpptr(rax, rsp);
|
||||
__ jcc(Assembler::equal, L);
|
||||
@ -1062,12 +1062,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
// allocate space for parameters
|
||||
__ movptr(method, STATE(_method));
|
||||
__ verify_oop(method);
|
||||
__ load_unsigned_word(t, Address(method, methodOopDesc::size_of_parameters_offset()));
|
||||
__ load_unsigned_short(t, Address(method, methodOopDesc::size_of_parameters_offset()));
|
||||
__ shll(t, 2);
|
||||
#ifdef _LP64
|
||||
__ subptr(rsp, t);
|
||||
__ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
|
||||
__ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI)
|
||||
__ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI)
|
||||
#else
|
||||
__ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror
|
||||
__ subptr(rsp, t);
|
||||
@ -1659,11 +1659,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
// const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock));
|
||||
|
||||
// get parameter size (always needed)
|
||||
__ load_unsigned_word(rcx, size_of_parameters);
|
||||
__ load_unsigned_short(rcx, size_of_parameters);
|
||||
|
||||
// rbx: methodOop
|
||||
// rcx: size of parameters
|
||||
__ load_unsigned_word(rdx, size_of_locals); // get size of locals in words
|
||||
__ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
|
||||
|
||||
__ subptr(rdx, rcx); // rdx = no. of additional locals
|
||||
|
||||
@ -1949,7 +1949,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
__ movptr(rbx, STATE(_result._to_call._callee));
|
||||
|
||||
// callee left args on top of expression stack, remove them
|
||||
__ load_unsigned_word(rcx, Address(rbx, methodOopDesc::size_of_parameters_offset()));
|
||||
__ load_unsigned_short(rcx, Address(rbx, methodOopDesc::size_of_parameters_offset()));
|
||||
__ lea(rsp, Address(rsp, rcx, Address::times_ptr));
|
||||
|
||||
__ movl(rcx, Address(rbx, methodOopDesc::result_index_offset()));
|
||||
@ -2119,7 +2119,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
// Make it look like call_stub calling conventions
|
||||
|
||||
// Get (potential) receiver
|
||||
__ load_unsigned_word(rcx, size_of_parameters); // get size of parameters in words
|
||||
__ load_unsigned_short(rcx, size_of_parameters); // get size of parameters in words
|
||||
|
||||
ExternalAddress recursive(CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation));
|
||||
__ pushptr(recursive.addr()); // make it look good in the debugger
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
|
@ -60,6 +60,7 @@ define_pd_global(uintx, NewSize, 1024 * K);
|
||||
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
|
||||
#endif // AMD64
|
||||
define_pd_global(intx, InlineFrequencyCount, 100);
|
||||
define_pd_global(intx, InlineSmallCode, 1000);
|
||||
define_pd_global(intx, PreInflateSpin, 10);
|
||||
|
||||
define_pd_global(intx, StackYellowPages, 2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
@ -192,7 +192,7 @@ void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, i
|
||||
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset) {
|
||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
||||
assert(cache != index, "must use different registers");
|
||||
load_unsigned_word(index, Address(rsi, bcp_offset));
|
||||
load_unsigned_short(index, Address(rsi, bcp_offset));
|
||||
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
|
||||
assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
|
||||
shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index
|
||||
@ -202,7 +202,7 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Regis
|
||||
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset) {
|
||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
||||
assert(cache != tmp, "must use different register");
|
||||
load_unsigned_word(tmp, Address(rsi, bcp_offset));
|
||||
load_unsigned_short(tmp, Address(rsi, bcp_offset));
|
||||
assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
|
||||
// convert from field index to ConstantPoolCacheEntry index
|
||||
// and from word offset to byte offset
|
||||
@ -219,47 +219,16 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, R
|
||||
// Resets EDI to locals. Register sub_klass cannot be any of the above.
|
||||
void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) {
|
||||
assert( Rsub_klass != rax, "rax, holds superklass" );
|
||||
assert( Rsub_klass != rcx, "rcx holds 2ndary super array length" );
|
||||
assert( Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr" );
|
||||
Label not_subtype, loop;
|
||||
assert( Rsub_klass != rcx, "used as a temp" );
|
||||
assert( Rsub_klass != rdi, "used as a temp, restored from locals" );
|
||||
|
||||
// Profile the not-null value's klass.
|
||||
profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi
|
||||
profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, reloads rdi
|
||||
|
||||
// Load the super-klass's check offset into ECX
|
||||
movl( rcx, Address(rax, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes() ) );
|
||||
// Load from the sub-klass's super-class display list, or a 1-word cache of
|
||||
// the secondary superclass list, or a failing value with a sentinel offset
|
||||
// if the super-klass is an interface or exceptionally deep in the Java
|
||||
// hierarchy and we have to scan the secondary superclass list the hard way.
|
||||
// See if we get an immediate positive hit
|
||||
cmpptr( rax, Address(Rsub_klass,rcx,Address::times_1) );
|
||||
jcc( Assembler::equal,ok_is_subtype );
|
||||
// Do the check.
|
||||
check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx
|
||||
|
||||
// Check for immediate negative hit
|
||||
cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
|
||||
jcc( Assembler::notEqual, not_subtype );
|
||||
// Check for self
|
||||
cmpptr( Rsub_klass, rax );
|
||||
jcc( Assembler::equal, ok_is_subtype );
|
||||
|
||||
// Now do a linear scan of the secondary super-klass chain.
|
||||
movptr( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) );
|
||||
// EDI holds the objArrayOop of secondary supers.
|
||||
movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length
|
||||
// Skip to start of data; also clear Z flag incase ECX is zero
|
||||
addptr( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) );
|
||||
// Scan ECX words at [EDI] for occurance of EAX
|
||||
// Set NZ/Z based on last compare
|
||||
repne_scan();
|
||||
restore_locals(); // Restore EDI; Must not blow flags
|
||||
// Not equal?
|
||||
jcc( Assembler::notEqual, not_subtype );
|
||||
// Must be equal but missed in cache. Update cache.
|
||||
movptr( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax );
|
||||
jmp( ok_is_subtype );
|
||||
|
||||
bind(not_subtype);
|
||||
// Profile the failure of the check.
|
||||
profile_typecheck_failed(rcx); // blows rcx
|
||||
}
|
||||
|
||||
@ -1031,7 +1000,7 @@ void InterpreterMacroAssembler::verify_method_data_pointer() {
|
||||
|
||||
// If the mdp is valid, it will point to a DataLayout header which is
|
||||
// consistent with the bcp. The converse is highly probable also.
|
||||
load_unsigned_word(rdx, Address(rcx, in_bytes(DataLayout::bci_offset())));
|
||||
load_unsigned_short(rdx, Address(rcx, in_bytes(DataLayout::bci_offset())));
|
||||
addptr(rdx, Address(rbx, methodOopDesc::const_offset()));
|
||||
lea(rdx, Address(rdx, constMethodOopDesc::codes_offset()));
|
||||
cmpptr(rdx, rsi);
|
||||
@ -1512,6 +1481,15 @@ void InterpreterMacroAssembler::notify_method_entry() {
|
||||
call_VM_leaf(
|
||||
CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), rcx, rbx);
|
||||
}
|
||||
|
||||
// RedefineClasses() tracing support for obsolete method entry
|
||||
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
|
||||
get_thread(rcx);
|
||||
get_method(rbx);
|
||||
call_VM_leaf(
|
||||
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
|
||||
rcx, rbx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009 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
|
||||
@ -190,7 +190,7 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
|
||||
int bcp_offset) {
|
||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
||||
assert(cache != index, "must use different registers");
|
||||
load_unsigned_word(index, Address(r13, bcp_offset));
|
||||
load_unsigned_short(index, Address(r13, bcp_offset));
|
||||
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
|
||||
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
||||
// convert from field index to ConstantPoolCacheEntry index
|
||||
@ -203,7 +203,7 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
|
||||
int bcp_offset) {
|
||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
||||
assert(cache != tmp, "must use different register");
|
||||
load_unsigned_word(tmp, Address(r13, bcp_offset));
|
||||
load_unsigned_short(tmp, Address(r13, bcp_offset));
|
||||
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
||||
// convert from field index to ConstantPoolCacheEntry index
|
||||
// and from word offset to byte offset
|
||||
@ -232,65 +232,13 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
|
||||
assert(Rsub_klass != rcx, "rcx holds 2ndary super array length");
|
||||
assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr");
|
||||
|
||||
Label not_subtype, not_subtype_pop, loop;
|
||||
|
||||
// Profile the not-null value's klass.
|
||||
profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi
|
||||
profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, reloads rdi
|
||||
|
||||
// Load the super-klass's check offset into rcx
|
||||
movl(rcx, Address(rax, sizeof(oopDesc) +
|
||||
Klass::super_check_offset_offset_in_bytes()));
|
||||
// Load from the sub-klass's super-class display list, or a 1-word
|
||||
// cache of the secondary superclass list, or a failing value with a
|
||||
// sentinel offset if the super-klass is an interface or
|
||||
// exceptionally deep in the Java hierarchy and we have to scan the
|
||||
// secondary superclass list the hard way. See if we get an
|
||||
// immediate positive hit
|
||||
cmpptr(rax, Address(Rsub_klass, rcx, Address::times_1));
|
||||
jcc(Assembler::equal,ok_is_subtype);
|
||||
// Do the check.
|
||||
check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx
|
||||
|
||||
// Check for immediate negative hit
|
||||
cmpl(rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes());
|
||||
jcc( Assembler::notEqual, not_subtype );
|
||||
// Check for self
|
||||
cmpptr(Rsub_klass, rax);
|
||||
jcc(Assembler::equal, ok_is_subtype);
|
||||
|
||||
// Now do a linear scan of the secondary super-klass chain.
|
||||
movptr(rdi, Address(Rsub_klass, sizeof(oopDesc) +
|
||||
Klass::secondary_supers_offset_in_bytes()));
|
||||
// rdi holds the objArrayOop of secondary supers.
|
||||
// Load the array length
|
||||
movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
|
||||
// Skip to start of data; also clear Z flag incase rcx is zero
|
||||
addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
// Scan rcx words at [rdi] for occurance of rax
|
||||
// Set NZ/Z based on last compare
|
||||
|
||||
// this part is kind tricky, as values in supers array could be 32 or 64 bit wide
|
||||
// and we store values in objArrays always encoded, thus we need to encode value
|
||||
// before repne
|
||||
if (UseCompressedOops) {
|
||||
push(rax);
|
||||
encode_heap_oop(rax);
|
||||
repne_scanl();
|
||||
// Not equal?
|
||||
jcc(Assembler::notEqual, not_subtype_pop);
|
||||
// restore heap oop here for movq
|
||||
pop(rax);
|
||||
} else {
|
||||
repne_scan();
|
||||
jcc(Assembler::notEqual, not_subtype);
|
||||
}
|
||||
// Must be equal but missed in cache. Update cache.
|
||||
movptr(Address(Rsub_klass, sizeof(oopDesc) +
|
||||
Klass::secondary_super_cache_offset_in_bytes()), rax);
|
||||
jmp(ok_is_subtype);
|
||||
|
||||
bind(not_subtype_pop);
|
||||
// restore heap oop here for miss
|
||||
if (UseCompressedOops) pop(rax);
|
||||
bind(not_subtype);
|
||||
// Profile the failure of the check.
|
||||
profile_typecheck_failed(rcx); // blows rcx
|
||||
}
|
||||
|
||||
@ -1063,7 +1011,7 @@ void InterpreterMacroAssembler::verify_method_data_pointer() {
|
||||
|
||||
// If the mdp is valid, it will point to a DataLayout header which is
|
||||
// consistent with the bcp. The converse is highly probable also.
|
||||
load_unsigned_word(c_rarg2,
|
||||
load_unsigned_short(c_rarg2,
|
||||
Address(c_rarg3, in_bytes(DataLayout::bci_offset())));
|
||||
addptr(c_rarg2, Address(rbx, methodOopDesc::const_offset()));
|
||||
lea(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset()));
|
||||
@ -1593,6 +1541,14 @@ void InterpreterMacroAssembler::notify_method_entry() {
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
|
||||
r15_thread, c_rarg1);
|
||||
}
|
||||
|
||||
// RedefineClasses() tracing support for obsolete method entry
|
||||
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
|
||||
get_method(c_rarg1);
|
||||
call_VM_leaf(
|
||||
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
|
||||
r15_thread, c_rarg1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2009 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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user