OpenJDK / jdk / jdk10
changeset 2670:a8af70ae4727
Merge
author | tbell |
---|---|
date | Mon, 20 Apr 2009 22:51:20 -0700 |
parents | 15024792697e a8134c4ee2cf |
children | 6407eaa188cd 0862f154383a |
files | corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jscheme.jar corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jschemelogutil.jar corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc.scm corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/run jaxp/make/jprt.config jaxws/make/jprt.config jdk/make/jprt.config jdk/src/share/classes/sun/misc/JavaIODeleteOnExitAccess.java jdk/src/share/classes/sun/text/normalizer/UProperty.java jdk/src/windows/classes/sun/awt/windows/fontconfig.98.properties jdk/src/windows/classes/sun/awt/windows/fontconfig.Me.properties jdk/src/windows/native/sun/windows/awt_KeyboardFocusManager.h langtools/make/jprt.config langtools/src/share/classes/com/sun/tools/classfile/OpCodes.java |
diffstat | 892 files changed, 64671 insertions(+), 17707 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Apr 20 22:50:16 2009 -0700 +++ b/.hgtags Mon Apr 20 22:51:20 2009 -0700 @@ -25,3 +25,8 @@ 1bf51a4c2627c2f0e0cbcc2cf0421bdb37f1f2b2 jdk7-b48 6b84b04a80afe23262377c60913eebfc898f14c4 jdk7-b49 5da0e6b9f4f18ef483c977337214b12ee0e1fc8f jdk7-b50 +a25c5ec5e40e07733d1ff9898a0abe36159288ff jdk7-b51 +7a90e89e36d103038f8667f6a7daae34ecfa1ad8 jdk7-b52 +d52186ee770dac57950536cd00ccbfdef360b04c jdk7-b53 +15096652c4d48dfb9fc0b2cb135304db94c65ba0 jdk7-b54 +c8b275d62d6b0a980c510e839b70292245863e85 jdk7-b55
--- a/.hgtags-top-repo Mon Apr 20 22:50:16 2009 -0700 +++ b/.hgtags-top-repo Mon Apr 20 22:51:20 2009 -0700 @@ -25,3 +25,8 @@ 4ae9f4bfdb98f65bd957e3fe72471b320150b38e jdk7-b48 aee93a8992d2389121eb610c00a86196f3e2b9b0 jdk7-b49 5111e13e44e542fe945b47ab154546daec36737d jdk7-b50 +0f0189d55ce4a1f7840da7582ac7d970b3b7ab15 jdk7-b51 +4264c2fe66493e57c411045a1b61377796641e45 jdk7-b52 +c235f4a8559d196879c56af80159f67ee5d0e720 jdk7-b53 +2ef382b1bbd58a68e668391c6145a4b2066c5b96 jdk7-b54 +aea0ace7a1e43619800931d42bbf69c579361c2d jdk7-b55
--- a/corba/.hgtags Mon Apr 20 22:50:16 2009 -0700 +++ b/corba/.hgtags Mon Apr 20 22:51:20 2009 -0700 @@ -25,3 +25,8 @@ 0be222241fd405e48915647facfaa176621b39b9 jdk7-b48 d70978bc64bc7a04be7797ab0dcd9b7b1b3a6bff jdk7-b49 0edbd0074b02b42b2b83cc47cb391d4869b7a8ec jdk7-b50 +3eb8f1047a7402a9a79937d1c39560e931e91da2 jdk7-b51 +bec82237d694f9802b820fa11bbb4f7fa9bf8e77 jdk7-b52 +3c4d73194f6f89f040ae3b2d257335dfa8a1b2b5 jdk7-b53 +8130ac858d6789d5853d23044ba4a992afda574a jdk7-b54 +7a869f16ba83060c34b77620406cfa89d1cd7084 jdk7-b55
--- a/corba/make/com/sun/corba/se/sources/Makefile Mon Apr 20 22:50:16 2009 -0700 +++ b/corba/make/com/sun/corba/se/sources/Makefile Mon Apr 20 22:51:20 2009 -0700 @@ -46,8 +46,6 @@ 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 @@ 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) #
--- a/corba/make/sun/rmi/corbalogsources/Makefile Mon Apr 20 22:50:16 2009 -0700 +++ b/corba/make/sun/rmi/corbalogsources/Makefile Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ 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 @@ $(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 @@ $(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) #
--- a/corba/make/tools/Makefile Mon Apr 20 22:50:16 2009 -0700 +++ b/corba/make/tools/Makefile Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ SUBDIRS = \ strip_properties \ idlj \ + logutil \ all build clean clobber:: $(SUBDIRS-loop)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/corba/make/tools/logutil/Makefile Mon Apr 20 22:51:20 2009 -0700 @@ -0,0 +1,43 @@ +# +# 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. +# + +# +# Makefile for building the idlj tool +# + +BUILDDIR = ../.. +PACKAGE = com.sun.tools.corba.se.logutil +PRODUCT = tools +PROGRAM = MC +include $(BUILDDIR)/common/Defs.gmk + +BUILDTOOL_SOURCE_ROOT = $(SHARE_SRC)/classes +BUILDTOOL_MAIN = $(PKGDIR)/MC.java + +# +# Build tool jar rules. +# +include $(BUILDDIR)/common/BuildToolJar.gmk +
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/IndentingPrintWriter.java Mon Apr 20 22:50:16 2009 -0700 +++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/IndentingPrintWriter.java Mon Apr 20 22:51:20 2009 -0700 @@ -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.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 @@ 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" ) ; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/Input.java Mon Apr 20 22:51:20 2009 -0700 @@ -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 + + "]"; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/InputCode.java Mon Apr 20 22:51:20 2009 -0700 @@ -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 + + "]"; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/InputException.java Mon Apr 20 22:51:20 2009 -0700 @@ -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 + + "]"; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/MC.java Mon Apr 20 22:51:20 2009 -0700 @@ -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 corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jschemelogutil.jar has changed
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc Mon Apr 20 22:50:16 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -#! /bin/sh -java -cp lib/jscheme.jar:lib/util.jar jscheme.REPL mc.scm -main main $@
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc.scm Mon Apr 20 22:50:16 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/run Mon Apr 20 22:50:16 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -#! /bin/sh -java -cp ${CLASSPATH}:lib/jscheme.jar:lib/util.jar jscheme.REPL mc.scm
--- a/hotspot/.hgtags Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/.hgtags Mon Apr 20 22:51:20 2009 -0700 @@ -25,3 +25,8 @@ bcb33806d186561c781992e5f4d8a90bb033f9f0 jdk7-b48 8b22ccb5aba2c6c11bddf6488a7bb7ef5b4bf2be jdk7-b49 dae503d9f04c1a11e182dbf7f770509c28dc0609 jdk7-b50 +2581d90c6c9b2012da930eb4742add94a03069a0 jdk7-b51 +1b1e8f1a4fe8cebc01c022484f78148e17b62a0d jdk7-b52 +032c6af894dae8d939b3dd31d82042549e7793e0 jdk7-b53 +fafab5d5349c7c066d677538db67a1ee0fb33bd2 jdk7-b54 +f8e839c086152da70d6ec5913ba6f9f509282e8d jdk7-b55
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Debugger.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Debugger.java Mon Apr 20 22:51:20 2009 -0700 @@ -118,9 +118,9 @@ 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;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerBase.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerBase.java Mon Apr 20 22:51:20 2009 -0700 @@ -56,8 +56,8 @@ // 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 @@ 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 @@ 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 @@ return heapOopSize; } - public long getHeapBase() { - return heapBase; + public long getNarrowOopBase() { + return narrowOopBase; } - public long getLogMinObjAlignmentInBytes() { - return logMinObjAlignmentInBytes; + public int getNarrowOopShift() { + return narrowOopShift; } }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/JVMDebugger.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/JVMDebugger.java Mon Apr 20 22:51:20 2009 -0700 @@ -42,5 +42,5 @@ long jintSize, long jlongSize, long jshortSize); - public void putHeapConst(long heapBase, long heapOopSize, long logMinObjAlignment); + public void putHeapConst(long heapOopSize, long narrowOopBase, int narrowOopShift); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebugger.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebugger.java Mon Apr 20 22:51:20 2009 -0700 @@ -65,9 +65,10 @@ 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;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Mon Apr 20 22:51:20 2009 -0700 @@ -85,9 +85,9 @@ 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);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerServer.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerServer.java Mon Apr 20 22:51:20 2009 -0700 @@ -114,17 +114,18 @@ 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);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java Mon Apr 20 22:51:20 2009 -0700 @@ -53,7 +53,8 @@ // 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 @@ 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 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);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Mon Apr 20 22:51:20 2009 -0700 @@ -142,34 +142,35 @@ // from jvm.h public static final long JVM_RECOGNIZED_CLASS_MODIFIERS = (JVM_ACC_PUBLIC | - JVM_ACC_FINAL | - JVM_ACC_SUPER | - JVM_ACC_INTERFACE | - JVM_ACC_ABSTRACT | - JVM_ACC_ANNOTATION | - JVM_ACC_SYNTHETIC); + JVM_ACC_FINAL | + JVM_ACC_SUPER | + JVM_ACC_INTERFACE | + JVM_ACC_ABSTRACT | + JVM_ACC_ANNOTATION | + JVM_ACC_ENUM | + JVM_ACC_SYNTHETIC); public static final long JVM_RECOGNIZED_FIELD_MODIFIERS = (JVM_ACC_PUBLIC | - JVM_ACC_PRIVATE | - JVM_ACC_PROTECTED | - JVM_ACC_STATIC | - JVM_ACC_FINAL | - JVM_ACC_VOLATILE | - JVM_ACC_TRANSIENT | - JVM_ACC_ENUM | - JVM_ACC_SYNTHETIC); + JVM_ACC_PRIVATE | + JVM_ACC_PROTECTED | + JVM_ACC_STATIC | + JVM_ACC_FINAL | + JVM_ACC_VOLATILE | + JVM_ACC_TRANSIENT | + JVM_ACC_ENUM | + JVM_ACC_SYNTHETIC); public static final long JVM_RECOGNIZED_METHOD_MODIFIERS = (JVM_ACC_PUBLIC | - JVM_ACC_PRIVATE | - JVM_ACC_PROTECTED | - JVM_ACC_STATIC | - JVM_ACC_FINAL | - JVM_ACC_SYNCHRONIZED | - JVM_ACC_BRIDGE | - JVM_ACC_VARARGS | - JVM_ACC_NATIVE | - JVM_ACC_ABSTRACT | - JVM_ACC_STRICT | - JVM_ACC_SYNTHETIC); + JVM_ACC_PRIVATE | + JVM_ACC_PROTECTED | + JVM_ACC_STATIC | + JVM_ACC_FINAL | + JVM_ACC_SYNCHRONIZED | + JVM_ACC_BRIDGE | + JVM_ACC_VARARGS | + JVM_ACC_NATIVE | + JVM_ACC_ABSTRACT | + JVM_ACC_STRICT | + JVM_ACC_SYNTHETIC); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java Mon Apr 20 22:51:20 2009 -0700 @@ -48,6 +48,8 @@ private static AddressField lastJavaPCField; private static CIntegerField threadStateField; private static AddressField osThreadField; + private static AddressField stackBaseField; + private static CIntegerField stackSizeField; private static JavaThreadPDAccess access; @@ -83,6 +85,8 @@ lastJavaPCField = anchorType.getAddressField("_last_Java_pc"); threadStateField = type.getCIntegerField("_thread_state"); osThreadField = type.getAddressField("_osthread"); + stackBaseField = type.getAddressField("_stack_base"); + stackSizeField = type.getCIntegerField("_stack_size"); UNINITIALIZED = db.lookupIntConstant("_thread_uninitialized").intValue(); NEW = db.lookupIntConstant("_thread_new").intValue(); @@ -312,6 +316,14 @@ return (OSThread) VMObjectFactory.newObject(OSThread.class, osThreadField.getValue(addr)); } + public Address getStackBase() { + return stackBaseField.getValue(); + } + + public long getStackSize() { + return stackSizeField.getValue(); + } + /** Gets the Java-side thread object for this JavaThread */ public Oop getThreadObj() { return VM.getVM().getObjectHeap().newOop(threadObjField.getValue(addr)); @@ -345,11 +357,18 @@ if (Assert.ASSERTS_ENABLED) { Assert.that(VM.getVM().isDebugging(), "Not yet implemented for non-debugging system"); } - Address highest = highestLock(); Address sp = lastSPDbg(); + Address stackBase = getStackBase(); // Be robust - if ((highest == null) || (sp == null)) return false; - return (highest.greaterThanOrEqual(a) && sp.lessThanOrEqual(a)); + if (sp == null) return false; + return stackBase.greaterThanOrEqual(a) && sp.lessThanOrEqual(a); + } + + public boolean isLockOwned(Address a) { + Address stackBase = getStackBase(); + Address stackLimit = stackBase.addOffsetTo(-getStackSize()); + + return stackBase.greaterThanOrEqual(a) && stackLimit.lessThanOrEqual(a); // FIXME: should traverse MonitorArray/MonitorChunks as in VM }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/StubRoutines.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/StubRoutines.java Mon Apr 20 22:51:20 2009 -0700 @@ -46,12 +46,18 @@ 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 { - callStubCompiledReturnAddressField = type.getAddressField("_call_stub_compiled_return"); + 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() {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java Mon Apr 20 22:51:20 2009 -0700 @@ -38,7 +38,6 @@ private static int HAS_ASYNC_EXCEPTION; private static AddressField activeHandlesField; - private static AddressField highestLockField; private static AddressField currentPendingMonitorField; private static AddressField currentWaitingMonitorField; @@ -60,7 +59,6 @@ tlabFieldOffset = type.getField("_tlab").getOffset(); activeHandlesField = type.getAddressField("_active_handles"); - highestLockField = type.getAddressField("_highest_lock"); currentPendingMonitorField = type.getAddressField("_current_pending_monitor"); currentWaitingMonitorField = type.getAddressField("_current_waiting_monitor"); } @@ -121,10 +119,6 @@ // pending exception } - public Address highestLock() { - return highestLockField.getValue(addr); - } - public ObjectMonitor getCurrentPendingMonitor() { Address monitorAddr = currentPendingMonitorField.getValue(addr); if (monitorAddr == null) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Mon Apr 20 22:51:20 2009 -0700 @@ -164,20 +164,11 @@ } } - long leastDiff = 0; - boolean leastDiffInitialized = false; - JavaThread theOwner = null; for (JavaThread thread = first(); thread != null; thread = thread.next()) { - Address addr = thread.highestLock(); - if (addr == null || addr.lessThan(o)) continue; - long diff = addr.minus(o); - if (!leastDiffInitialized || diff < leastDiff) { - leastDiffInitialized = true; - leastDiff = diff; - theOwner = thread; - } + if (thread.isLockOwned(o)) + return thread; } - return theOwner; + return null; } public JavaThread owningThreadFromMonitor(ObjectMonitor monitor) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Mon Apr 20 22:51:20 2009 -0700 @@ -342,11 +342,14 @@ 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 */
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Mon Apr 20 22:51:20 2009 -0700 @@ -89,29 +89,6 @@ // update the code buffer hotspot specific bytecode with the jvm bytecode code[bci] = (byte) (0xFF & bytecode); - // RewriteFrequentPairs - if(hotspotcode == Bytecodes._fast_iaccess_0 || - hotspotcode == Bytecodes._fast_aaccess_0 || - hotspotcode == Bytecodes._fast_faccess_0) { - // rewrite next bytecode as _getfield - bci++; - code[bci] = (byte) (0xFF & Bytecodes._getfield); - bytecode = Bytecodes._getfield; - hotspotcode = Bytecodes._getfield; - } else if (hotspotcode == Bytecodes._fast_iload2) { - // rewrite next bytecode as _iload - bci++; - code[bci] = (byte) (0xFF & Bytecodes._iload); - bytecode = Bytecodes._iload; - hotspotcode = Bytecodes._iload; - } else if (hotspotcode == Bytecodes._fast_icaload) { - // rewrite next bytecode as _caload - bci++; - code[bci] = (byte) (0xFF & Bytecodes._caload); - bytecode = Bytecodes._caload; - bytecode = Bytecodes._caload; - } - short cpoolIndex = 0; switch (bytecode) { // bytecodes with ConstantPoolCache index
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Mon Apr 20 22:51:20 2009 -0700 @@ -59,8 +59,14 @@ SystemDictionary dict = VM.getVM().getSystemDictionary(); dict.classesDo(new SystemDictionary.ClassVisitor() { public void visit(Klass k) { - if (k instanceof InstanceKlass) - dumpKlass((InstanceKlass) k); + if (k instanceof InstanceKlass) { + try { + dumpKlass((InstanceKlass) k); + } catch (Exception e) { + System.out.println(k.getName().asString()); + e.printStackTrace(); + } + } } }); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Mon Apr 20 22:51:20 2009 -0700 @@ -40,7 +40,6 @@ protected InstanceKlass klass; protected DataOutputStream dos; protected ConstantPool cpool; - protected boolean is15Format; // Map between class name to index of type CONSTANT_Class protected Map classToIndex = new HashMap(); @@ -73,7 +72,6 @@ klass = kls; dos = new DataOutputStream(os); cpool = klass.getConstants(); - is15Format = is15ClassFile(); } public void write() throws IOException { @@ -82,7 +80,7 @@ // write magic dos.writeInt(0xCAFEBABE); - writeVersion(is15Format); + writeVersion(); writeConstantPool(); writeClassAccessFlags(); writeThisClass(); @@ -96,43 +94,14 @@ dos.flush(); } - protected boolean is15ClassFile() { - // if klass has generic signature, then it is 1.5 class file. - if (klass.getGenericSignature() != null) { - return true; - } - - // if atleast one method has generic signature - // , then we have 1.5 class file. - ObjArray methods = klass.getMethods(); - final int numMethods = (int) methods.getLength(); - for (int m = 0; m < numMethods; m++) { - Method curMethod = (Method) methods.getObjAt(m); - if (curMethod.getGenericSignature() != null) { - return true; - } - } - - // if atleast one field has non-zero generic signature index, then we have - // 1.5 class file - TypeArray fields = klass.getFields(); - final int numFields = (int) fields.getLength(); - for (int f = 0; f < numFields; f += InstanceKlass.NEXT_OFFSET) { - short genSigIndex = fields.getShortAt(f + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET); - if (genSigIndex != (short)0) return true; - } - - return false; + protected void writeVersion() throws IOException { + dos.writeShort((short)klass.minorVersion()); + dos.writeShort((short)klass.majorVersion()); } - protected void writeVersion(boolean is15Format) throws IOException { - if (is15Format) { - dos.writeShort(MINOR_VERSION); - dos.writeShort(MAJOR_VERSION); - } else { - dos.writeShort(MINOR_VERSION_OLD); - dos.writeShort(MAJOR_VERSION_OLD); - } + protected void writeIndex(int index) throws IOException { + if (index == 0) throw new InternalError(); + dos.writeShort(index); } protected void writeConstantPool() throws IOException { @@ -392,8 +361,8 @@ if (DEBUG) debugMessage("\tfield name = " + nameIndex + ", signature = " + signatureIndex); short fieldAttributeCount = 0; - boolean isSyn = isSynthetic(accessFlags); - if (isSyn) + boolean hasSyn = hasSyntheticAttribute(accessFlags); + if (hasSyn) fieldAttributeCount++; short initvalIndex = fields.getShortAt(index + InstanceKlass.INITVAL_INDEX_OFFSET); @@ -407,18 +376,18 @@ dos.writeShort(fieldAttributeCount); // write synthetic, if applicable - if (isSyn) + if (hasSyn) writeSynthetic(); if (initvalIndex != 0) { - dos.writeShort(_constantValueIndex); + writeIndex(_constantValueIndex); dos.writeInt(2); dos.writeShort(initvalIndex); if (DEBUG) debugMessage("\tfield init value = " + initvalIndex); } if (genSigIndex != 0) { - dos.writeShort(_signatureIndex); + writeIndex(_signatureIndex); dos.writeInt(2); dos.writeShort(genSigIndex); if (DEBUG) debugMessage("\tfield generic signature index " + genSigIndex); @@ -430,8 +399,13 @@ return (accessFlags & (short) JVM_ACC_SYNTHETIC) != 0; } + protected boolean hasSyntheticAttribute(short accessFlags) { + // Check if flags have the attribute and if the constant pool contains an entry for it. + return isSynthetic(accessFlags) && _syntheticIndex != 0; + } + protected void writeSynthetic() throws IOException { - dos.writeShort(_syntheticIndex); + writeIndex(_syntheticIndex); dos.writeInt(0); } @@ -459,8 +433,8 @@ short methodAttributeCount = 0; - final boolean isSyn = isSynthetic((short)accessFlags); - if (isSyn) + final boolean hasSyn = hasSyntheticAttribute((short)accessFlags); + if (hasSyn) methodAttributeCount++; final boolean hasCheckedExceptions = m.hasCheckedExceptions(); @@ -478,27 +452,11 @@ dos.writeShort(methodAttributeCount); if (DEBUG) debugMessage("\tmethod attribute count = " + methodAttributeCount); - if (isSyn) { + if (hasSyn) { if (DEBUG) debugMessage("\tmethod is synthetic"); writeSynthetic(); } - if (hasCheckedExceptions) { - CheckedExceptionElement[] exceptions = m.getCheckedExceptions(); - dos.writeShort(_exceptionsIndex); - - int attrSize = 2 /* number_of_exceptions */ + - exceptions.length * 2 /* exception_index */; - dos.writeInt(attrSize); - dos.writeShort(exceptions.length); - if (DEBUG) debugMessage("\tmethod has " + exceptions.length - + " checked exception(s)"); - for (int e = 0; e < exceptions.length; e++) { - short cpIndex = (short) exceptions[e].getClassCPIndex(); - dos.writeShort(cpIndex); - } - } - if (isCodeAvailable) { byte[] code = m.getByteCode(); short codeAttrCount = 0; @@ -574,7 +532,7 @@ // start writing Code - dos.writeShort(_codeIndex); + writeIndex(_codeIndex); dos.writeInt(codeSize); if (DEBUG) debugMessage("\tcode attribute length = " + codeSize); @@ -608,7 +566,7 @@ // write LineNumberTable, if available. if (hasLineNumberTable) { - dos.writeShort(_lineNumberTableIndex); + writeIndex(_lineNumberTableIndex); dos.writeInt(lineNumberAttrLen); dos.writeShort((short) lineNumberTable.length); for (int l = 0; l < lineNumberTable.length; l++) { @@ -619,7 +577,7 @@ // write LocalVariableTable, if available. if (hasLocalVariableTable) { - dos.writeShort((short) _localVariableTableIndex); + writeIndex((short) _localVariableTableIndex); dos.writeInt(localVarAttrLen); dos.writeShort((short) localVariableTable.length); for (int l = 0; l < localVariableTable.length; l++) { @@ -632,6 +590,22 @@ } } + if (hasCheckedExceptions) { + CheckedExceptionElement[] exceptions = m.getCheckedExceptions(); + writeIndex(_exceptionsIndex); + + int attrSize = 2 /* number_of_exceptions */ + + exceptions.length * 2 /* exception_index */; + dos.writeInt(attrSize); + dos.writeShort(exceptions.length); + if (DEBUG) debugMessage("\tmethod has " + exceptions.length + + " checked exception(s)"); + for (int e = 0; e < exceptions.length; e++) { + short cpIndex = (short) exceptions[e].getClassCPIndex(); + dos.writeShort(cpIndex); + } + } + if (isGeneric) { writeGenericSignature(m.getGenericSignature().asString()); } @@ -643,7 +617,7 @@ } protected void writeGenericSignature(String signature) throws IOException { - dos.writeShort(_signatureIndex); + writeIndex(_signatureIndex); if (DEBUG) debugMessage("signature attribute = " + _signatureIndex); dos.writeInt(2); Short index = (Short) utf8ToIndex.get(signature); @@ -653,12 +627,12 @@ protected void writeClassAttributes() throws IOException { final long flags = klass.getAccessFlags(); - final boolean isSyn = isSynthetic((short) flags); + final boolean hasSyn = hasSyntheticAttribute((short) flags); // check for source file short classAttributeCount = 0; - if (isSyn) + if (hasSyn) classAttributeCount++; Symbol sourceFileName = klass.getSourceFileName(); @@ -677,12 +651,12 @@ dos.writeShort(classAttributeCount); if (DEBUG) debugMessage("class attribute count = " + classAttributeCount); - if (isSyn) + if (hasSyn) writeSynthetic(); // write SourceFile, if any if (sourceFileName != null) { - dos.writeShort(_sourceFileIndex); + writeIndex(_sourceFileIndex); if (DEBUG) debugMessage("source file attribute = " + _sourceFileIndex); dos.writeInt(2); Short index = (Short) utf8ToIndex.get(sourceFileName.asString()); @@ -697,7 +671,7 @@ // write inner classes, if any if (numInnerClasses != 0) { - dos.writeShort(_innerClassesIndex); + writeIndex(_innerClassesIndex); final int innerAttrLen = 2 /* number_of_inner_classes */ + numInnerClasses * ( 2 /* inner_class_info_index */ +
--- a/hotspot/make/hotspot_version Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/hotspot_version Mon Apr 20 22:51:20 2009 -0700 @@ -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_MAJOR_VER=16 HS_MINOR_VER=0 -HS_BUILD_NUMBER=03 +HS_BUILD_NUMBER=01 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/hotspot/make/jprt.config Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/jprt.config Mon Apr 20 22:51:20 2009 -0700 @@ -73,6 +73,7 @@ else if [ "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6" -o \ "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6u10" -o \ + "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6u14" -o \ "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6perf" ] ; then # All jdk6 builds use SS11 compiler_name=SS11
--- a/hotspot/make/jprt.properties Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/jprt.properties Mon Apr 20 22:51:20 2009 -0700 @@ -19,12 +19,12 @@ # 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. -# +# # # Properties for jprt -# All build result bundles are full jdks, so the 64bit testing does not +# All build result bundles are full jdks, so the 64bit testing does not # need the 32bit sibling bundle installed. # Note: If the hotspot/make/Makefile changed to only bundle the 64bit files # when bundling 64bit, and stripped out the 64bit files from any 32bit @@ -89,60 +89,52 @@ ${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}-{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}-{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}-{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}-{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
--- a/hotspot/make/windows/build_vm_def.sh Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/build_vm_def.sh Mon Apr 20 22:51:20 2009 -0700 @@ -52,6 +52,19 @@ 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
--- a/hotspot/make/windows/create.bat Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/create.bat Mon Apr 20 22:51:20 2009 -0700 @@ -72,12 +72,20 @@ 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 **************************************************************
--- a/hotspot/make/windows/get_msc_ver.sh Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/get_msc_ver.sh Mon Apr 20 22:51:20 2009 -0700 @@ -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
--- a/hotspot/make/windows/makefiles/adlc.make Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/makefiles/adlc.make Mon Apr 20 22:51:20 2009 -0700 @@ -46,6 +46,7 @@ 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" \
--- a/hotspot/make/windows/makefiles/compile.make Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/makefiles/compile.make Mon Apr 20 22:51:20 2009 -0700 @@ -170,10 +170,6 @@ # 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 @@ # 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.
--- a/hotspot/make/windows/makefiles/makedeps.make Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/makefiles/makedeps.make Mon Apr 20 22:51:20 2009 -0700 @@ -48,6 +48,8 @@ $(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 @@ -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
--- a/hotspot/make/windows/makefiles/rules.make Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/makefiles/rules.make Mon Apr 20 22:51:20 2009 -0700 @@ -42,10 +42,23 @@ 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
--- a/hotspot/make/windows/makefiles/sa.make Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/makefiles/sa.make Mon Apr 20 22:51:20 2009 -0700 @@ -89,9 +89,11 @@ 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
--- a/hotspot/make/windows/makefiles/sanity.make Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/make/windows/makefiles/sanity.make Mon Apr 20 22:51:20 2009 -0700 @@ -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.
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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,12 +2615,12 @@ } } -RegisterConstant MacroAssembler::delayed_value(intptr_t* delayed_value_addr, - Register tmp, - int offset) { +RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr, + Register tmp, + int offset) { intptr_t value = *delayed_value_addr; if (value != 0) - return RegisterConstant(value + offset); + return RegisterOrConstant(value + offset); // load indirectly to solve generation ordering problem Address a(tmp, (address) delayed_value_addr); @@ -2634,11 +2634,11 @@ if (offset != 0) add(tmp, offset, tmp); - return RegisterConstant(tmp); + return RegisterOrConstant(tmp); } -void MacroAssembler::regcon_inc_ptr( RegisterConstant& dest, RegisterConstant src, Register temp ) { +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)) { @@ -2647,15 +2647,15 @@ 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 = RegisterConstant(res); // side effect seen by caller + 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 = RegisterConstant(temp); // side effect seen by caller + dest = RegisterOrConstant(temp); // side effect seen by caller } } -void MacroAssembler::regcon_sll_ptr( RegisterConstant& dest, RegisterConstant src, Register temp ) { +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); @@ -2666,12 +2666,12 @@ sll_ptr(dest.as_register(), src, dest.as_register()); } else if (src.is_constant()) { intptr_t res = dest.as_constant() << src.as_constant(); - dest = RegisterConstant(res); // side effect seen by caller + 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 = RegisterConstant(temp); // side effect seen by caller + dest = RegisterOrConstant(temp); // side effect seen by caller } } @@ -2683,7 +2683,7 @@ // On failure, execution transfers to the given label. void MacroAssembler::lookup_interface_method(Register recv_klass, Register intf_klass, - RegisterConstant itable_index, + RegisterOrConstant itable_index, Register method_result, Register scan_temp, Register sethi_temp, @@ -2720,7 +2720,7 @@ add(recv_klass, scan_temp, scan_temp); // Adjust recv_klass by scaled itable_index, so we can free itable_index. - RegisterConstant itable_offset = 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); @@ -2767,6 +2767,320 @@ } +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::check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type) { + assert_different_registers(mtype_reg, mh_reg, temp_reg); + // compare method type against that of the receiver + RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg); + ld_ptr(mh_reg, mhtype_offset, temp_reg); + cmp(temp_reg, mtype_reg); + br(Assembler::notEqual, false, Assembler::pn, wrong_method_type); + delayed()->nop(); +} + + +void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) { + assert(mh_reg == G3_method_handle, "caller must put MH object in G3"); + assert_different_registers(mh_reg, temp_reg); + + // pick out the interpreted side of the handler + ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg); + + // off we go... + ld_ptr(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes(), temp_reg); + jmp(temp_reg, 0); + + // for the various stubs which take control at this point, + // see MethodHandles::generate_method_handle_stub + + // (Can any caller use this delay slot? If so, add an option for supression.) + delayed()->nop(); +} + +RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot, + int extra_slot_offset) { + // cf. TemplateTable::prepare_invoke(), if (load_receiver). + int stackElementSize = Interpreter::stackElementWords() * wordSize; + int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0); + int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1); + assert(offset1 - offset == stackElementSize, "correct arithmetic"); + if (arg_slot.is_constant()) { + offset += arg_slot.as_constant() * stackElementSize; + return offset; + } else { + Register temp = arg_slot.as_register(); + sll_ptr(temp, exact_log2(stackElementSize), temp); + if (offset != 0) + add(temp, offset, temp); + return temp; + } +} + + + void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg, Label& done, Label* slow_case, @@ -3972,7 +4286,6 @@ 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) { @@ -3985,25 +4298,19 @@ 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(); @@ -4210,7 +4517,7 @@ } // Loading values by size and signed-ness -void MacroAssembler::load_sized_value(Register s1, RegisterConstant s2, Register d, +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: @@ -4316,7 +4623,13 @@ 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 @@ -4338,26 +4651,39 @@ 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); - sub(r, G6_heapbase, 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); - sub(src, G6_heapbase, dst); - srlx(dst, LogMinObjAlignmentInBytes, dst); + 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); - bpr(rc_nz, true, Assembler::pt, dst, done); - delayed() -> add(dst, G6_heapbase, dst); // annuled if not taken - bind(done); + 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); } @@ -4366,8 +4692,11 @@ // 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); - add(r, G6_heapbase, r); + if (Universe::narrow_oop_base() != NULL) + add(r, G6_heapbase, r); } void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) { @@ -4375,14 +4704,17 @@ // 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); - add(dst, G6_heapbase, 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); } }
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ -84,6 +84,10 @@ REGISTER_DECLARATION(Register, Gtemp , G5); +// JSR 292 fixed register usages: +REGISTER_DECLARATION(Register, G5_method_type , G5); +REGISTER_DECLARATION(Register, G3_method_handle , G3); + // The compiler requires that G5_megamorphic_method is G5_inline_cache_klass, // because a single patchable "set" instruction (NativeMovConstReg, // or NativeMovConstPatching for compiler1) instruction @@ -91,9 +95,13 @@ // call site is an inline cache or is megamorphic. See the function // CompiledIC::set_to_megamorphic. // -// On the other hand, G5_inline_cache_klass must differ from G5_method, -// because both registers are needed for an inline cache that calls -// an interpreted method. +// If a inline cache targets an interpreted method, then the +// G5 register will be used twice during the call. First, +// the call site will be patched to load a compiledICHolder +// into G5. (This is an ordered pair of ic_klass, method.) +// The c2i adapter will first check the ic_klass, then load +// G5_method with the method part of the pair just before +// jumping into the interpreter. // // Note that G5_method is only the method-self for the interpreter, // and is logically unrelated to G5_megamorphic_method. @@ -1088,8 +1096,8 @@ 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, RegisterConstant s2, Register d, int offset = 0); - inline void add( const Address& a, Register d, int offset = 0); + 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) ); } void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } @@ -1305,15 +1313,15 @@ 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, RegisterConstant s2, Register d ); - inline void ldsb( Register s1, RegisterConstant s2, Register d ); - inline void lduh( Register s1, RegisterConstant s2, Register d ); - inline void ldsh( Register s1, RegisterConstant s2, Register d ); - inline void lduw( Register s1, RegisterConstant s2, Register d ); - inline void ldsw( Register s1, RegisterConstant s2, Register d ); - inline void ldx( Register s1, RegisterConstant s2, Register d ); - inline void ld( Register s1, RegisterConstant s2, Register d ); - inline void ldd( Register s1, RegisterConstant s2, Register d ); + 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 @@ -1535,12 +1543,12 @@ 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, RegisterConstant s2 ); - inline void sth( Register d, Register s1, RegisterConstant s2 ); - inline void stw( Register d, Register s1, RegisterConstant s2 ); - inline void stx( Register d, Register s1, RegisterConstant s2 ); - inline void std( Register d, Register s1, RegisterConstant s2 ); - inline void st( Register d, Register s1, RegisterConstant s2 ); + 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 @@ -1859,7 +1867,7 @@ // 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, RegisterConstant s2, 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 ); @@ -1931,6 +1939,7 @@ inline void store_ptr_contents( Register s, Address& a, int offset = 0 ); inline void jumpl_to( Address& a, Register d, int offset = 0 ); inline void jump_to( Address& a, int offset = 0 ); + inline void jump_indirect_to( Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0 ); // ring buffer traceable jumps @@ -1965,26 +1974,26 @@ // 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, RegisterConstant s2, 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, RegisterConstant s2 ); + 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, RegisterConstant s2, 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, RegisterConstant s2 ); + 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, RegisterConstant s2, Register d, + void load_sized_value(Register s1, RegisterOrConstant s2, Register d, int size_in_bytes, bool is_signed); // Helpers for address formation. @@ -1994,11 +2003,11 @@ // 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( RegisterConstant& dest, RegisterConstant src, + void regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp = noreg ); - void regcon_sll_ptr( RegisterConstant& dest, RegisterConstant src, + void regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp = noreg ); - RegisterConstant ensure_rs2(RegisterConstant rs2, Register sethi_temp) { + 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 @@ -2322,11 +2331,61 @@ // interface method calling void lookup_interface_method(Register recv_klass, Register intf_klass, - RegisterConstant itable_index, + 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); + + // method handles (JSR 292) + void check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type); + void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); + // offset relative to Gargs of argument at tos[arg_slot]. + // (arg_slot == 0 means the last argument, not the first). + RegisterOrConstant argument_offset(RegisterOrConstant arg_slot, + int extra_slot_offset = 0); + + // Stack overflow checking // Note: this clobbers G3_scratch @@ -2341,7 +2400,7 @@ // stack overflow + shadow pages. Clobbers tsp and scratch registers. void bang_stack_size(Register Rsize, Register Rtsp, Register Rscratch); - virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp, int offset); + virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset); void verify_tlab();
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -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,45 +143,45 @@ inline void Assembler::ld( Register s1, int simm13a, Register d) { lduw( s1, simm13a, d); } #endif -inline void Assembler::ldub( Register s1, RegisterConstant s2, Register d) { +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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register 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, RegisterConstant s2, Register d, int offset) { +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); @@ -243,23 +243,23 @@ 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, RegisterConstant s2) { +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, RegisterConstant s2) { +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, RegisterConstant s2) { +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, RegisterConstant s2) { +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, RegisterConstant s2) { +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()); } @@ -308,7 +308,7 @@ #endif } -inline void MacroAssembler::ld_ptr( Register s1, RegisterConstant s2, Register d ) { +inline void MacroAssembler::ld_ptr( Register s1, RegisterOrConstant s2, Register d ) { #ifdef _LP64 Assembler::ldx( s1, s2, d); #else @@ -340,7 +340,7 @@ #endif } -inline void MacroAssembler::st_ptr( Register d, Register s1, RegisterConstant s2 ) { +inline void MacroAssembler::st_ptr( Register d, Register s1, RegisterOrConstant s2 ) { #ifdef _LP64 Assembler::stx( d, s1, s2); #else @@ -373,7 +373,7 @@ #endif } -inline void MacroAssembler::ld_long( Register s1, RegisterConstant s2, Register d ) { +inline void MacroAssembler::ld_long( Register s1, RegisterOrConstant s2, Register d ) { #ifdef _LP64 Assembler::ldx(s1, s2, d); #else @@ -405,7 +405,7 @@ #endif } -inline void MacroAssembler::st_long( Register d, Register s1, RegisterConstant s2 ) { +inline void MacroAssembler::st_long( Register d, Register s1, RegisterOrConstant s2 ) { #ifdef _LP64 Assembler::stx(d, s1, s2); #else @@ -455,7 +455,7 @@ #endif } -inline void MacroAssembler::sll_ptr( Register s1, RegisterConstant s2, Register d ) { +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); } @@ -671,6 +671,15 @@ } +inline void MacroAssembler::jump_indirect_to( Address& a, Register temp, + int ld_offset, int jmp_offset ) { + assert_not_delayed(); + //sethi(a); // sethi is caller responsibility for this one + ld_ptr(a, temp, ld_offset); + jmp(temp, jmp_offset); +} + + inline void MacroAssembler::set_oop( jobject obj, Register d ) { set_oop(allocate_oop_address(obj, d)); }
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ // 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(); - - // 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); + + // 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,58 +2481,30 @@ __ 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(); - } 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"); - __ 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); + 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 { - 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"); + // 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); __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); __ delayed()->nop(); - __ bind(done); } - + __ bind(done); } __ mov(obj, dst); } else if (code == lir_instanceof) { @@ -2582,58 +2542,32 @@ __ 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();
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -714,38 +714,19 @@ // 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 }
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ -1017,6 +1017,7 @@ const int slop_factor = 2*wordSize; const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor? + //6815692//methodOopDesc::extra_stack_words() + // extra push slots for MH adapters frame::memory_parameter_word_sp_offset + // register save area + param window (native ? frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class @@ -1163,6 +1164,9 @@ __ st_ptr(O2, XXX_STATE(_stack)); // PREPUSH __ lduh(max_stack, O3); // Full size expression stack + guarantee(!EnableMethodHandles, "no support yet for java.dyn.MethodHandle"); //6815692 + //6815692//if (EnableMethodHandles) + //6815692// __ inc(O3, methodOopDesc::extra_stack_entries()); __ sll(O3, LogBytesPerWord, O3); __ sub(O2, O3, O3); // __ sub(O3, wordSize, O3); // so prepush doesn't look out of bounds @@ -2017,7 +2021,9 @@ const int fixed_size = sizeof(BytecodeInterpreter)/wordSize + // interpreter state object frame::memory_parameter_word_sp_offset; // register save area + param window + const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); return (round_to(max_stack + + extra_stack + slop_factor + fixed_size + monitor_size + @@ -2104,7 +2110,8 @@ // Need +1 here because stack_base points to the word just above the first expr stack entry // and stack_limit is supposed to point to the word just below the last expr stack entry. // See generate_compute_interpreter_state. - to_fill->_stack_limit = stack_base - (method->max_stack() + 1); + int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); + to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack); to_fill->_monitor_base = (BasicObjectLock*) monitor_base; // sparc specific
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -46,6 +46,7 @@ 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);
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -866,65 +866,18 @@ 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 ); - - // 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_fast_path(Rsub_klass, Rsuper_klass, + Rtmp1, Rtmp2, + &ok_is_subtype, ¬_subtype, NULL); + + 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);
--- a/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 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 @@ -29,6 +29,7 @@ address generate_normal_entry(bool synchronized); address generate_native_entry(bool synchronized); address generate_abstract_entry(void); + address generate_method_handle_entry(void); address generate_math_entry(AbstractInterpreter::MethodKind kind); address generate_empty_entry(void); address generate_accessor_entry(void);
--- a/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 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 @@ -235,6 +235,19 @@ } + +// Method handle invoker +// Dispatch a method of the form java.dyn.MethodHandles::invoke(...) +address InterpreterGenerator::generate_method_handle_entry(void) { + if (!EnableMethodHandles) { + return generate_abstract_entry(); + } + return generate_abstract_entry(); //6815692// +} + + + + //---------------------------------------------------------------------------------------------------- // Entry points & stack frame layout // @@ -364,6 +377,7 @@ case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; + case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break; case Interpreter::java_lang_math_sin : break; case Interpreter::java_lang_math_cos : break; case Interpreter::java_lang_math_tan : break;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -0,0 +1,70 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_methodHandles_sparc.cpp.incl" + +#define __ _masm-> + +address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, + address interpreted_entry) { + __ align(wordSize); + address target = __ pc() + sizeof(Data); + while (__ pc() < target) { + __ nop(); + __ align(wordSize); + } + + MethodHandleEntry* me = (MethodHandleEntry*) __ pc(); + me->set_end_address(__ pc()); // set a temporary end_address + me->set_from_interpreted_entry(interpreted_entry); + me->set_type_checking_entry(NULL); + + return (address) me; +} + +MethodHandleEntry* MethodHandleEntry::finish_compiled_entry(MacroAssembler* _masm, + address start_addr) { + MethodHandleEntry* me = (MethodHandleEntry*) start_addr; + assert(me->end_address() == start_addr, "valid ME"); + + // Fill in the real end_address: + __ align(wordSize); + me->set_end_address(__ pc()); + + return me; +} + + +// Code generation +address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { + ShouldNotReachHere(); //NYI, 6815692 + return NULL; +} + +// Generate an "entry" field for a method handle. +// This determines how the method handle will respond to calls. +void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { + ShouldNotReachHere(); //NYI, 6815692 +}
--- a/hotspot/src/cpu/sparc/vm/register_definitions_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/register_definitions_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ -142,6 +142,8 @@ REGISTER_DEFINITION(Register, G3_scratch); REGISTER_DEFINITION(Register, G4_scratch); REGISTER_DEFINITION(Register, Gtemp); +REGISTER_DEFINITION(Register, G5_method_type); +REGISTER_DEFINITION(Register, G3_method_handle); REGISTER_DEFINITION(Register, Lentry_args); #ifdef CC_INTERP
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ -937,12 +937,12 @@ // Inputs: // G2_thread - TLS // G5_method - Method oop - // O0 - Flag telling us to restore SP from O5 - // O4_args - Pointer to interpreter's args - // O5 - Caller's saved SP, to be restored if needed + // G4 (Gargs) - Pointer to interpreter's args + // O0..O4 - free for scratch + // O5_savedSP - Caller's saved SP, to be restored if needed // O6 - Current SP! // O7 - Valid return address - // L0-L7, I0-I7 - Caller's temps (no frame pushed yet) + // L0-L7, I0-I7 - Caller's temps (no frame pushed yet) // Outputs: // G2_thread - TLS @@ -954,7 +954,7 @@ // F0-F7 - more outgoing args - // O4 is about to get loaded up with compiled callee's args + // Gargs is the incoming argument base, and also an outgoing argument. __ sub(Gargs, BytesPerWord, Gargs); #ifdef ASSERT
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/sparc.ad Mon Apr 20 22:51:20 2009 -0700 @@ -547,7 +547,11 @@ 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; } @@ -1601,9 +1605,11 @@ 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"); - st->print_cr("\tADD R_G5,R_G6_heap_base,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"); } @@ -2502,7 +2508,11 @@ __ load_klass(O0, G3_scratch); int klass_load_size; if (UseCompressedOops) { - klass_load_size = 3*BytesPerInstWord; + 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 @@ __ 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; @@ -9005,6 +9211,52 @@ 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--------------------------------------------------
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -817,21 +817,6 @@ 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 @@ __ 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 @@ Register L2_super = L2; Register L3_index = L3; -#ifdef _LP64 - Register L4_ooptmp = L4; - - 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() ); + __ check_klass_subtype_slow_path(Rsub, Rsuper, + L0, L1, L2, L3, + NULL, &miss); + + // 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 @@ __ delayed()->restore(); #endif - // Hit or miss falls through here __ BIND(miss); __ addcc(G0,1,Rret); // set NZ flags, NZ result @@ -2330,51 +2258,31 @@ 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 @@ 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 @@ // 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 @@ 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);
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ -108,6 +108,24 @@ } +// Arguments are: required type in G5_method_type, and +// failing object (or NULL) in G3_method_handle. +address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { + address entry = __ pc(); + // expression stack must be empty before entering the VM if an exception + // happened + __ empty_expression_stack(); + // load exception object + __ call_VM(Oexception, + CAST_FROM_FN_PTR(address, + InterpreterRuntime::throw_WrongMethodTypeException), + G5_method_type, // required + G3_method_handle); // actual + __ should_not_reach_here(); + return entry; +} + + address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) { address entry = __ pc(); // expression stack must be empty before entering the VM if an exception happened @@ -448,6 +466,7 @@ const int extra_space = rounded_vm_local_words + // frame local scratch space + //6815692//methodOopDesc::extra_stack_words() + // extra push slots for MH adapters frame::memory_parameter_word_sp_offset + // register save area (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0); @@ -1447,6 +1466,7 @@ round_to(callee_extra_locals * Interpreter::stackElementWords(), WordsPerLong); const int max_stack_words = max_stack * Interpreter::stackElementWords(); return (round_to((max_stack_words + //6815692//+ methodOopDesc::extra_stack_words() + rounded_vm_local_words + frame::memory_parameter_word_sp_offset), WordsPerLong) // already rounded
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ 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 @@ 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
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -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 @@ -25,34 +25,38 @@ 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 + v8_instructions = 0, + 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 { - unknown_m = 0, - all_features_m = -1, + unknown_m = 0, + all_features_m = -1, - v8_instructions_m = 1 << v8_instructions, - hardware_int_muldiv_m = 1 << hardware_int_muldiv, - hardware_fsmuld_m = 1 << hardware_fsmuld, - v9_instructions_m = 1 << v9_instructions, - vis1_instructions_m = 1 << vis1_instructions, - vis2_instructions_m = 1 << vis2_instructions, - sun4v_m = 1 << sun4v_instructions, + v8_instructions_m = 1 << v8_instructions, + 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, - niagara1_m = generic_v9_m | niagara1_unique_m + niagara1_unique_m = sun4v_m, + niagara1_m = generic_v9_m | niagara1_unique_m }; static int _features; @@ -62,7 +66,7 @@ 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 @@ // 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; }
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -114,6 +114,9 @@ (int)(s->code_end() - __ pc())); } guarantee(__ pc() <= s->code_end(), "overflowed buffer"); + // shut the door on sizing bugs + int slop = 2*BytesPerInstWord; // 32-bit offset is this much larger than a 13-bit one + assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for sethi;add"); s->set_exception_points(npe_addr, ame_addr); return s; @@ -208,6 +211,9 @@ (int)(s->code_end() - __ pc())); } guarantee(__ pc() <= s->code_end(), "overflowed buffer"); + // shut the door on sizing bugs + int slop = 2*BytesPerInstWord; // 32-bit offset is this much larger than a 13-bit one + assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for sethi;add"); s->set_exception_points(npe_addr, ame_addr); return s; @@ -221,16 +227,62 @@ 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 { const int basic = (28 LP64_ONLY(+ 6)) * 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); } } + + // In order to tune these parameters, run the JVM with VM options + // +PrintMiscellaneous and +WizardMode to see information about + // actual itable stubs. Look for lines like this: + // itable #1 at 0x5551212[116] left over: 8 + // Reduce the constants so that the "left over" number is 8 + // Do not aim at a left-over number of zero, because a very + // large vtable or itable offset (> 4K) will require an extra + // sethi/or pair of instructions. + // + // The JVM98 app. _202_jess has a megamorphic interface call. + // The itable code looks like this: + // Decoding VtableStub itbl[1]@16 + // ld [ %o0 + 4 ], %g3 + // save %sp, -64, %sp + // ld [ %g3 + 0xe8 ], %l2 + // sll %l2, 2, %l2 + // add %l2, 0x134, %l2 + // and %l2, -8, %l2 ! NOT_LP64 only + // add %g3, %l2, %l2 + // add %g3, 4, %g3 + // ld [ %l2 ], %l5 + // brz,pn %l5, throw_icce + // cmp %l5, %g5 + // be %icc, success + // add %l2, 8, %l2 + // loop: + // ld [ %l2 ], %l5 + // brz,pn %l5, throw_icce + // cmp %l5, %g5 + // bne,pn %icc, loop + // add %l2, 8, %l2 + // success: + // ld [ %l2 + -4 ], %l2 + // ld [ %g3 + %l2 ], %l5 + // restore %l5, 0, %g5 + // ld [ %g5 + 0x44 ], %g3 + // jmp %g3 + // nop + // throw_icce: + // sethi %hi(throw_ICCE_entry), %g3 + // ! 5 more instructions here, LP64_ONLY + // jmp %g3 + %lo(throw_ICCE_entry) + // restore }
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -727,7 +727,7 @@ } #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 @@ -1438,26 +1438,12 @@ } } -// 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 - 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 - } - } + NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");) + emit_byte( 0x0F ); + emit_byte( 0xAE ); + emit_byte( 0xF0 ); } void Assembler::mov(Register dst, Register src) { @@ -2187,12 +2173,56 @@ 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); } @@ -2325,6 +2355,29 @@ 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); @@ -3224,12 +3277,6 @@ 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 @@ -3249,6 +3296,12 @@ 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); @@ -3857,6 +3910,37 @@ 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(), "")); @@ -4049,6 +4133,25 @@ 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); @@ -7149,7 +7252,7 @@ // On failure, execution transfers to the given label. void MacroAssembler::lookup_interface_method(Register recv_klass, Register intf_klass, - RegisterConstant itable_index, + RegisterOrConstant itable_index, Register method_result, Register scan_temp, Label& L_no_such_interface) { @@ -7217,6 +7320,225 @@ } +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)); } @@ -7262,12 +7584,12 @@ } -RegisterConstant MacroAssembler::delayed_value(intptr_t* delayed_value_addr, - Register tmp, - int offset) { +RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr, + Register tmp, + int offset) { intptr_t value = *delayed_value_addr; if (value != 0) - return RegisterConstant(value + offset); + return RegisterOrConstant(value + offset); // load indirectly to solve generation ordering problem movptr(tmp, ExternalAddress((address) delayed_value_addr)); @@ -7283,7 +7605,84 @@ if (offset != 0) addptr(tmp, offset); - return RegisterConstant(tmp); + return RegisterOrConstant(tmp); +} + + +// registers on entry: +// - rax ('check' register): required MethodType +// - rcx: method handle +// - rdx, rsi, or ?: killable temp +void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type) { + if (UseCompressedOops) unimplemented(); // field accesses must decode + // compare method type against that of the receiver + cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); + jcc(Assembler::notEqual, wrong_method_type); +} + + +// A method handle has a "vmslots" field which gives the size of its +// argument list in JVM stack slots. This field is either located directly +// in every method handle, or else is indirectly accessed through the +// method handle's MethodType. This macro hides the distinction. +void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, + Register temp_reg) { + if (UseCompressedOops) unimplemented(); // field accesses must decode + // load mh.type.form.vmslots + if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) { + // hoist vmslots into every mh to avoid dependent load chain + movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg))); + } else { + Register temp2_reg = vmslots_reg; + movptr(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); + movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg))); + movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg))); + } +} + + +// registers on entry: +// - rcx: method handle +// - rdx: killable temp (interpreted only) +// - rax: killable temp (compiled only) +void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) { + assert(mh_reg == rcx, "caller must put MH object in rcx"); + assert_different_registers(mh_reg, temp_reg); + + if (UseCompressedOops) unimplemented(); // field accesses must decode + + // pick out the interpreted side of the handler + movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg))); + + // off we go... + jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); + + // for the various stubs which take control at this point, + // see MethodHandles::generate_method_handle_stub +} + + +Address MacroAssembler::argument_address(RegisterOrConstant arg_slot, + int extra_slot_offset) { + // cf. TemplateTable::prepare_invoke(), if (load_receiver). + int stackElementSize = Interpreter::stackElementSize(); + int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0); +#ifdef ASSERT + int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1); + assert(offset1 - offset == stackElementSize, "correct arithmetic"); +#endif + Register scale_reg = noreg; + Address::ScaleFactor scale_factor = Address::no_scale; + if (arg_slot.is_constant()) { + offset += arg_slot.as_constant() * stackElementSize; + } else { + scale_reg = arg_slot.as_register(); + scale_factor = Address::times(stackElementSize); + } + offset += wordSize; // return PC is on stack + return Address(rsp, scale_reg, scale_factor, offset); } @@ -7710,14 +8109,21 @@ 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())); - movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_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 - { - movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); - movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - } + { + movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } } void MacroAssembler::store_klass(Register dst, Register src) { @@ -7760,11 +8166,20 @@ // 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); @@ -7780,6 +8195,7 @@ 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; @@ -7790,12 +8206,18 @@ } #endif verify_oop(r, "broken oop in encode_heap_oop_not_null"); - subq(r, r12_heapbase); - shrq(r, LogMinObjAlignmentInBytes); + 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; @@ -7809,18 +8231,32 @@ if (dst != src) { movq(dst, src); } - subq(dst, r12_heapbase); - shrq(dst, LogMinObjAlignmentInBytes); + 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); @@ -7844,32 +8280,76 @@ 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"); - leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); + 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"); - leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); + 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(oop_recorder() != NULL, "this assembler needs an OopRecorder"); + 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
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -212,7 +212,7 @@ "inconsistent address"); } - Address(Register base, RegisterConstant index, ScaleFactor scale = times_1, int disp = 0) + Address(Register base, RegisterOrConstant index, ScaleFactor scale = times_1, int disp = 0) : _base (base), _index(index.register_or_noreg()), _scale(scale), @@ -256,7 +256,7 @@ "inconsistent address"); } - Address(Register base, RegisterConstant index, ScaleFactor scale, ByteSize disp) + Address(Register base, RegisterOrConstant index, ScaleFactor scale, ByteSize disp) : _base (base), _index(index.register_or_noreg()), _scale(scale), @@ -578,20 +578,25 @@ // 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 @@ -1063,15 +1068,23 @@ 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 (order_constraint & StoreLoad) { - // MFENCE subsumes LFENCE - mfence(); - } /* [jk] not needed currently: else if (order_constraint & LoadLoad) { - lfence(); - } */ + if (os::is_MP()) { + // We only have to handle StoreLoad + if (order_constraint & StoreLoad) { + // 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(); @@ -1213,12 +1226,24 @@ 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); @@ -1239,6 +1264,10 @@ // 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); @@ -1647,6 +1676,9 @@ 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(); @@ -1786,11 +1818,55 @@ // interface method calling void lookup_interface_method(Register recv_klass, Register intf_klass, - RegisterConstant itable_index, + 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); + + // method handles (JSR 292) + void check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type); + void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, + Register temp_reg); + void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); + Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0); + + //---- void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 @@ -1833,9 +1909,9 @@ // stack overflow + shadow pages. Also, clobbers tmp void bang_stack_size(Register size, Register tmp); - virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr, - Register tmp, - int offset); + 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);
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -1598,18 +1598,9 @@ // 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 @@ } __ 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 @@ __ 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)));
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -1354,6 +1354,13 @@ 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 @@ 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 @@ __ 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 @@ __ 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);
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -513,10 +513,11 @@ // compute full expression stack limit const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); + const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_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)); + __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack)); __ movptr(STATE(_stack_limit), rsp); } @@ -659,8 +660,9 @@ // 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; + const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); __ 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(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor)); __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); #ifdef ASSERT @@ -2185,6 +2187,7 @@ case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; + case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break; case Interpreter::java_lang_math_sin : // fall thru case Interpreter::java_lang_math_cos : // fall thru @@ -2224,7 +2227,8 @@ const int overhead_size = sizeof(BytecodeInterpreter)/wordSize + ( frame::sender_sp_offset - frame::link_offset) + 2; - const int method_stack = (method->max_locals() + method->max_stack()) * + const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); + const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * Interpreter::stackElementWords(); return overhead_size + method_stack + stub_code; } @@ -2289,7 +2293,8 @@ // Need +1 here because stack_base points to the word just above the first expr stack entry // and stack_limit is supposed to point to the word just below the last expr stack entry. // See generate_compute_interpreter_state. - to_fill->_stack_limit = stack_base - (method->max_stack() + 1); + int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); + to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1); to_fill->_monitor_base = (BasicObjectLock*) monitor_base; to_fill->_self_link = to_fill; @@ -2335,7 +2340,8 @@ monitor_size); // Now with full size expression stack - int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord; + int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); + int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord; // and now with only live portion of the expression stack short_frame_size = short_frame_size + tempcount * BytesPerWord;
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -60,6 +60,7 @@ 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);
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -219,47 +219,16 @@ // 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 } @@ -586,13 +555,18 @@ } -// Jump to from_interpreted entry of a call unless single stepping is possible -// in this thread in which case we must call the i2i entry -void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { +void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() { // set sender sp lea(rsi, Address(rsp, wordSize)); // record last_sp movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); +} + + +// Jump to from_interpreted entry of a call unless single stepping is possible +// in this thread in which case we must call the i2i entry +void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { + prepare_to_jump_from_interpreted(); if (JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code;
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp Mon Apr 20 22:51:20 2009 -0700 @@ -161,6 +161,7 @@ // jump to an invoked target + void prepare_to_jump_from_interpreted(); void jump_from_interpreted(Register method, Register temp); // Returning from interpreted functions
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Apr 20 22:50:16 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Apr 20 22:51:20 2009 -0700 @@ -232,65 +232,13 @@ 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, reloads rdi - // Profile the not-null value's klass. - profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi + // Do the check. + check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx - // 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); - - // 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 } @@ -603,13 +551,18 @@ MacroAssembler::call_VM_leaf_base(entry_point, 3); } -// Jump to from_interpreted entry of a call unless single stepping is possible -// in this thread in which case we must call the i2i entry -void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { +void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() { // set sender sp lea(r13, Address(rsp, wordSize)); // record last_sp movptr(Address(rbp, frame::interpreter_frame_last_sp_o