From a968eabd507357fa7bb923eb8098dd420ebd8685 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 14 Jun 2013 15:49:41 +0100 Subject: [PATCH 001/152] 8011157: Improve CORBA portablility Fix also reviewed by Alexander Fomin Reviewed-by: alanb, coffeys, skoivu --- common/makefiles/RMICompilation.gmk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/makefiles/RMICompilation.gmk b/common/makefiles/RMICompilation.gmk index 4727412e958..acbc7054ceb 100644 --- a/common/makefiles/RMICompilation.gmk +++ b/common/makefiles/RMICompilation.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,11 +60,11 @@ define SetupRMICompilation ifneq (,$$($1_RUN_IIOP)) $1_TARGETS += $$($1_TIE_FILES) - $1_ARGS += -iiop + $1_ARGS += -iiop -emitPermissionCheck endif ifneq (,$$($1_RUN_IIOP_STDPKG)) $1_TARGETS += $$($1_TIE_STDPKG_FILES) - $1_ARGS2 := -iiop -standardPackage + $1_ARGS2 := -iiop -emitPermissionCheck -standardPackage endif ifneq (,$$($1_KEEP_GENERATED)) From 3f85c00fb2c68a4762e7b8851eb9c06158fd4146 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 14 Jun 2013 16:31:55 +0100 Subject: [PATCH 002/152] 8011157: Improve CORBA portablility Fix also reviewed by Alexander Fomin Reviewed-by: alanb, coffeys, skoivu --- .../corba/se/impl/transport/SelectorImpl.java | 4 +- .../sun/rmi/rmic/iiop/StubGenerator.java | 75 ++++++++++++++++++- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java index 7bd98805ab7..054071b7d8b 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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 @@ -55,7 +55,7 @@ import com.sun.corba.se.impl.orbutil.ORBUtility; /** * @author Harold Carr */ -public class SelectorImpl +class SelectorImpl extends Thread implements diff --git a/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java b/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java index aa3c6bea2f5..0d41c1edb90 100644 --- a/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java +++ b/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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 @@ -34,6 +34,9 @@ package sun.rmi.rmic.iiop; import java.io.File; import java.io.IOException; +import java.io.SerializablePermission; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; @@ -49,6 +52,7 @@ import com.sun.corba.se.impl.util.Utility; import com.sun.corba.se.impl.util.PackagePrefixChecker; import sun.rmi.rmic.Main; + /** * An IIOP stub/tie generator for rmic. * @@ -78,6 +82,7 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { protected boolean castArray = false; protected Hashtable transactionalObjects = new Hashtable() ; protected boolean POATie = false ; + protected boolean emitPermissionCheck = false; /** * Default constructor for Main to use. @@ -193,6 +198,9 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { } else if (argv[i].equals("-standardPackage")) { standardPackage = true; argv[i] = null; + } else if (argv[i].equals("-emitPermissionCheck")) { + emitPermissionCheck = true; + argv[i] = null; } else if (arg.equals("-xstubbase")) { argv[i] = null; if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) { @@ -390,9 +398,22 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { writePackageAndImports(p); +// generate +// import java.security.AccessController; +// import java.security.PrivilegedAction; +// import java.io.SerializablePermission; + if (emitPermissionCheck) { + p.pln("import java.security.AccessController;"); + p.pln("import java.security.PrivilegedAction;"); + p.pln("import java.io.SerializablePermission;"); + p.pln(); + p.pln(); + } + // Declare the stub class; implement all remote interfaces. p.p("public class " + currentClass); + p.p(" extends " + getName(stubBaseClass)); p.p(" implements "); if (remoteInterfaces.length > 0) { @@ -422,6 +443,57 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { writeIds( p, theType, false ); p.pln(); + if (emitPermissionCheck) { + + // produce the following generated code for example + // private static Void checkPermission() { + // SecurityManager sm = System.getSecurityManager(); + // if (sm != null) { + // sm.checkPermission(new SerializablePermission( + // "enableSubclassImplementation")); // testing + // } + // return null; + // } + // + // private _XXXXX_Stub(Void ignore) { + // } + // + // public _XXXXX_Stub() { + // this(checkPermission()); + // } + // + // where XXXXX is the name of the remote interface + + p.pln(); + p.plnI("private static Void checkPermission() {"); + p.plnI("SecurityManager sm = System.getSecurityManager();"); + p.pln("if (sm != null) {"); + p.pI(); + p.plnI("sm.checkPermission(new SerializablePermission("); + p.plnI("\"enableSubclassImplementation\"));"); + p.pO(); + p.pO(); + p.pOln("}"); + p.pln("return null;"); + p.pO(); + p.pOln("}"); + p.pln(); + p.pO(); + + p.pI(); + p.pln("private " + currentClass + "(Void ignore) { }"); + p.pln(); + + p.plnI("public " + currentClass + "() { "); + p.pln("this(checkPermission());"); + p.pOln("}"); + p.pln(); + } + + if (!emitPermissionCheck) { + p.pI(); + } + // Write the _ids() method... p.plnI("public String[] _ids() { "); @@ -815,7 +887,6 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { CompoundType theType) throws IOException { // Wtite the method declaration and opening brace... - String methodName = method.getName(); String methodIDLName = method.getIDLName(); From 8379a071b6408db6a1089a3c079638719cf34acf Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 11 Jul 2013 12:59:03 -0400 Subject: [PATCH 003/152] 8016256: Make finalization final Add private methods to final methods check Reviewed-by: coleenp, acorn, ahgross --- hotspot/src/share/vm/classfile/classFileParser.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 65cd2333a9d..f764057f101 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -4481,9 +4481,8 @@ void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass for (int index = 0; index < num_methods; index++) { Method* m = methods->at(index); - // skip private, static and methods - if ((!m->is_private()) && - (!m->is_static()) && + // skip static and methods + if ((!m->is_static()) && (m->name() != vmSymbols::object_initializer_name())) { Symbol* name = m->name(); From b9c256373a815672c9c560483097de86ddfacebe Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 16 Jul 2013 14:06:04 -0700 Subject: [PATCH 004/152] 8012425: Transform TransformerFactory Reviewed-by: alanb, dfuchs, mullan --- .../internal/xsltc/trax/TransformerImpl.java | 2 + .../xalan/internal/xsltc/trax/Util.java | 7 ++ .../validation/StreamValidatorHelper.java | 35 +++--- .../jaxp/validation/ValidatorHandlerImpl.java | 2 + .../internal/parsers/AbstractSAXParser.java | 37 +++--- .../internal/parsers/XML11Configuration.java | 111 +++++++++--------- .../xml/internal/utils/XMLReaderManager.java | 20 +++- 7 files changed, 122 insertions(+), 92 deletions(-) diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index 63446e734e2..7c33c91a8c8 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java @@ -271,6 +271,7 @@ public final class TransformerImpl extends Transformer _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD); _readerManager = XMLReaderManager.getInstance(_useServicesMechanism); _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); + _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing); //_isIncremental = tfactory._incremental; } @@ -286,6 +287,7 @@ public final class TransformerImpl extends Transformer */ public void setSecureProcessing(boolean flag) { _isSecureProcessing = flag; + _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing); } /** * Return the state of the services mechanism feature. diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java index 25c45c04be9..b287a351db4 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java @@ -105,6 +105,13 @@ public final class Util { if (reader == null) { try { reader= XMLReaderFactory.createXMLReader(); + try { + reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, + xsltc.isSecureProcessing()); + } catch (SAXNotRecognizedException e) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + e.getMessage()); + } } catch (Exception e ) { try { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index 1b4f6875611..95fe7d8d8ec 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -20,28 +20,27 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; -import java.lang.ref.SoftReference; -import java.io.IOException; - -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.XMLConstants; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.parsers.XML11Configuration; +import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; +import java.io.IOException; +import java.lang.ref.SoftReference; +import javax.xml.XMLConstants; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; import org.xml.sax.SAXException; /** @@ -86,6 +85,11 @@ final class StreamValidatorHelper implements ValidatorHelper { Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; private static final String DEFAULT_TRANSFORMER_IMPL = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"; + + /** Property id: security manager. */ + private static final String SECURITY_MANAGER = + Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + // // Data // @@ -165,6 +169,9 @@ final class StreamValidatorHelper implements ValidatorHelper { private XMLParserConfiguration initialize() { XML11Configuration config = new XML11Configuration(); + if (fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) { + config.setProperty(SECURITY_MANAGER, new SecurityManager()); + } config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); XMLErrorReporter errorReporter = (XMLErrorReporter) fComponentManager.getProperty(ERROR_REPORTER); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java index 3f493517209..2c3a9842c5e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java @@ -674,6 +674,8 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(true); try { + spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, + fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); reader = spf.newSAXParser().getXMLReader(); // If this is a Xerces SAX parser, set the security manager if there is one if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java index 726f31e76b5..53ad2a6b605 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java @@ -20,16 +20,13 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.IOException; -import java.util.Locale; - import com.sun.org.apache.xerces.internal.impl.Constants; -import com.sun.org.apache.xerces.internal.util.Status; -import com.sun.org.apache.xerces.internal.xs.PSVIProvider; -import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper; +import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; +import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolHash; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.xni.Augmentations; @@ -48,15 +45,17 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; import com.sun.org.apache.xerces.internal.xs.AttributePSVI; import com.sun.org.apache.xerces.internal.xs.ElementPSVI; +import com.sun.org.apache.xerces.internal.xs.PSVIProvider; +import java.io.IOException; +import java.util.Locale; +import javax.xml.XMLConstants; import org.xml.sax.AttributeList; -import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.DocumentHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; -import org.xml.sax.Locator; import org.xml.sax.Parser; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; @@ -131,6 +130,10 @@ public abstract class AbstractSAXParser protected static final String DOM_NODE = Constants.SAX_PROPERTY_PREFIX + Constants.DOM_NODE_PROPERTY; + /** Property id: security manager. */ + private static final String SECURITY_MANAGER = + Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Recognized properties. */ private static final String[] RECOGNIZED_PROPERTIES = { LEXICAL_HANDLER, @@ -1645,19 +1648,13 @@ public abstract class AbstractSAXParser // Drop through and perform default processing // } - - // - // Xerces Features - // - - /* - else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) { - String feature = featureId.substring(XERCES_FEATURES_PREFIX.length()); - // - // Drop through and perform default processing - // + else if (featureId.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { + if (state) { + if (fConfiguration.getProperty(SECURITY_MANAGER )==null) { + fConfiguration.setProperty(SECURITY_MANAGER, new SecurityManager()); + } + } } - */ // // Default handling diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 32ac6a86d78..b33a5f4093e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -20,14 +20,6 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.Properties; -import javax.xml.XMLConstants; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl; @@ -53,7 +45,6 @@ import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; -import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; @@ -72,6 +63,11 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import javax.xml.XMLConstants; /** * This class is the configuration used to parse XML 1.0 and XML 1.1 documents. @@ -453,26 +449,26 @@ public class XML11Configuration extends ParserConfigurationSettings XMLGrammarPool grammarPool, XMLComponentManager parentSettings) { - super(parentSettings); + super(parentSettings); - // create a vector to hold all the components in use - // XML 1.0 specialized components - fComponents = new ArrayList(); - // XML 1.1 specialized components - fXML11Components = new ArrayList(); - // Common components for XML 1.1. and XML 1.0 - fCommonComponents = new ArrayList(); + // create a vector to hold all the components in use + // XML 1.0 specialized components + fComponents = new ArrayList(); + // XML 1.1 specialized components + fXML11Components = new ArrayList(); + // Common components for XML 1.1. and XML 1.0 + fCommonComponents = new ArrayList(); - // create table for features and properties - fFeatures = new HashMap(); - fProperties = new HashMap(); + // create table for features and properties + fFeatures = new HashMap(); + fProperties = new HashMap(); // add default recognized features final String[] recognizedFeatures = { CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl - VALIDATION, - NAMESPACES, + VALIDATION, + NAMESPACES, NORMALIZE_DATA, SCHEMA_ELEMENT_DEFAULT, SCHEMA_AUGMENT_PSVI, GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS, HONOUR_ALL_SCHEMALOCATIONS, NAMESPACE_GROWTH, @@ -483,47 +479,48 @@ public class XML11Configuration extends ParserConfigurationSettings // features might not have been set and it would cause a // not-recognized exception to be thrown. -Ac XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING, - EXTERNAL_GENERAL_ENTITIES, - EXTERNAL_PARAMETER_ENTITIES, - PARSER_SETTINGS, - XMLConstants.FEATURE_SECURE_PROCESSING + EXTERNAL_GENERAL_ENTITIES, + EXTERNAL_PARAMETER_ENTITIES, + PARSER_SETTINGS, + XMLConstants.FEATURE_SECURE_PROCESSING }; + addRecognizedFeatures(recognizedFeatures); - // set state for default features - fFeatures.put(VALIDATION, Boolean.FALSE); - fFeatures.put(NAMESPACES, Boolean.TRUE); - fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE); - fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE); - fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); - fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); - fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE); - fFeatures.put(NORMALIZE_DATA, Boolean.TRUE); - fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE); - fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); - fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE); - fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE); - fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE); - fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE); - fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE); - fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); - fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); + // set state for default features + fFeatures.put(VALIDATION, Boolean.FALSE); + fFeatures.put(NAMESPACES, Boolean.TRUE); + fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE); + fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE); + fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); + fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); + fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE); + fFeatures.put(NORMALIZE_DATA, Boolean.TRUE); + fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE); + fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); + fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE); + fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE); + fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE); + fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE); + fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE); + fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); + fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); // add default recognized properties final String[] recognizedProperties = { - SYMBOL_TABLE, - ERROR_HANDLER, - ENTITY_RESOLVER, + SYMBOL_TABLE, + ERROR_HANDLER, + ENTITY_RESOLVER, ERROR_REPORTER, ENTITY_MANAGER, DOCUMENT_SCANNER, DTD_SCANNER, DTD_PROCESSOR, DTD_VALIDATOR, - DATATYPE_VALIDATOR_FACTORY, - VALIDATION_MANAGER, - SCHEMA_VALIDATOR, - XML_STRING, + DATATYPE_VALIDATOR_FACTORY, + VALIDATION_MANAGER, + SCHEMA_VALIDATOR, + XML_STRING, XMLGRAMMAR_POOL, JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, @@ -540,15 +537,15 @@ public class XML11Configuration extends ParserConfigurationSettings }; addRecognizedProperties(recognizedProperties); - if (symbolTable == null) { - symbolTable = new SymbolTable(); - } - fSymbolTable = symbolTable; - fProperties.put(SYMBOL_TABLE, fSymbolTable); + if (symbolTable == null) { + symbolTable = new SymbolTable(); + } + fSymbolTable = symbolTable; + fProperties.put(SYMBOL_TABLE, fSymbolTable); fGrammarPool = grammarPool; if (fGrammarPool != null) { - fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); + fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); } fEntityManager = new XMLEntityManager(); diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index 28002037272..279ac53a71f 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -26,11 +26,13 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; import java.util.HashMap; + import javax.xml.XMLConstants; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; @@ -63,6 +65,8 @@ public class XMLReaderManager { private HashMap m_inUse; private boolean m_useServicesMechanism = true; + + private boolean _secureProcessing; /** * protocols allowed for external DTD references in source file and/or stylesheet. */ @@ -118,7 +122,12 @@ public class XMLReaderManager { // TransformerFactory creates a reader via the // XMLReaderFactory if setXMLReader is not used reader = XMLReaderFactory.createXMLReader(); - + try { + reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _secureProcessing); + } catch (SAXNotRecognizedException e) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + e.getMessage()); + } } catch (Exception e) { try { // If unable to create an instance, let's try to use @@ -192,6 +201,15 @@ public class XMLReaderManager { m_useServicesMechanism = flag; } + /** + * Set feature + */ + public void setFeature(String name, boolean value) { + if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { + _secureProcessing = value; + } + } + /** * Get property value */ From 8b314fcc50688a3ae85c2caf68105e2759496c20 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 17 Jul 2013 09:31:39 -0700 Subject: [PATCH 005/152] 8017298: Better XML support Reviewed-by: alanb, dfuchs, mullan, lancea --- .../impl/XMLDocumentFragmentScannerImpl.java | 11 +- .../internal/impl/XMLEntityManager.java | 16 +- .../xerces/internal/impl/XMLScanner.java | 33 ++- .../internal/impl/msg/XMLMessages.properties | 1 + .../impl/xs/models/CMNodeFactory.java | 23 +- .../xs/traversers/XSAttributeChecker.java | 3 +- .../impl/xs/traversers/XSDHandler.java | 6 +- .../internal/jaxp/DocumentBuilderImpl.java | 4 +- .../xerces/internal/jaxp/SAXParserImpl.java | 6 +- .../validation/StreamValidatorHelper.java | 4 +- .../jaxp/validation/ValidatorHandlerImpl.java | 4 +- .../jaxp/validation/XMLSchemaFactory.java | 14 +- .../XMLSchemaValidatorComponentManager.java | 10 +- .../internal/parsers/AbstractSAXParser.java | 4 +- .../parsers/SecurityConfiguration.java | 6 +- .../xerces/internal/util/SecurityManager.java | 226 ------------------ .../xerces/internal/util/SymbolTable.java | 4 +- .../internal/utils/XMLSecurityManager.java | 147 ++++++++++++ .../internal/xinclude/XIncludeHandler.java | 10 +- .../com/sun/xml/internal/stream/Entity.java | 2 +- 20 files changed, 247 insertions(+), 287 deletions(-) delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index 82c009bbdd3..d76a7e22a7e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -50,9 +50,9 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.xml.internal.stream.Entity; import javax.xml.XMLConstants; @@ -382,7 +382,7 @@ public class XMLDocumentFragmentScannerImpl protected boolean foundBuiltInRefs = false; - protected SecurityManager fSecurityManager = null; + protected XMLSecurityManager fSecurityManager = null; //skip element algorithm static final short MAX_DEPTH_LIMIT = 5 ; @@ -569,8 +569,10 @@ public class XMLDocumentFragmentScannerImpl // xerces features fReportCdataEvent = componentManager.getFeature(Constants.STAX_REPORT_CDATA_EVENT, true); - fSecurityManager = (SecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null); - fElementAttributeLimit = (fSecurityManager != null)?fSecurityManager.getElementAttrLimit():0; + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null); + fElementAttributeLimit = (fSecurityManager != null)? + fSecurityManager.getLimit(XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT):0; + fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS, false); @@ -951,6 +953,7 @@ public class XMLDocumentFragmentScannerImpl // scan decl super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings); + fMarkupDepth--; // pseudo-attribute values diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index ee6ff0a6b2e..5ecd1215a82 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -28,9 +28,9 @@ import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.util.*; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; @@ -324,7 +324,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { // stores defaults for entity expansion limit if it has // been set on the configuration. - protected SecurityManager fSecurityManager = null; + protected XMLSecurityManager fSecurityManager = null; /** * True if the document entity is standalone. This should really @@ -1482,7 +1482,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fEntityResolver = (XMLEntityResolver)componentManager.getProperty(ENTITY_RESOLVER, null); fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null); fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null); - fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); // JAXP 1.5 feature fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT); @@ -1499,7 +1499,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { // a class acting as a component manager but not // implementing that interface for whatever reason. public void reset() { - fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0; + fEntityExpansionLimit = (fSecurityManager != null)? + fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; + // initialize state fStandalone = false; @@ -1635,8 +1637,10 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { } if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { - fSecurityManager = (SecurityManager)value; - fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0; + fSecurityManager = (XMLSecurityManager)value; + fEntityExpansionLimit = (fSecurityManager != null)? + fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; + } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 0c66aa236fa..9fc489b3e02 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -499,7 +499,7 @@ public abstract class XMLScanner reportFatalError("SDDeclInvalid", new Object[] {standalone}); } } else { - reportFatalError("EncodingDeclRequired", null); + reportFatalError("SDDeclNameInvalid", null); } break; } @@ -564,7 +564,7 @@ public abstract class XMLScanner XMLString value) throws IOException, XNIException { - String name = fEntityScanner.scanName(); + String name = scanPseudoAttributeName(); // XMLEntityManager.print(fEntityManager.getCurrentEntity()); if (name == null) { @@ -616,6 +616,35 @@ public abstract class XMLScanner } // scanPseudoAttribute(XMLString):String + /** + * Scans the name of a pseudo attribute. The only legal names + * in XML 1.0/1.1 documents are 'version', 'encoding' and 'standalone'. + * + * @return the name of the pseudo attribute or null + * if a legal pseudo attribute name could not be scanned. + */ + private String scanPseudoAttributeName() throws IOException, XNIException { + final int ch = fEntityScanner.peekChar(); + switch (ch) { + case 'v': + if (fEntityScanner.skipString(fVersionSymbol)) { + return fVersionSymbol; + } + break; + case 'e': + if (fEntityScanner.skipString(fEncodingSymbol)) { + return fEncodingSymbol; + } + break; + case 's': + if (fEntityScanner.skipString(fStandaloneSymbol)) { + return fStandaloneSymbol; + } + break; + } + return null; + } // scanPseudoAttributeName() + /** * Scans a processing instruction. *

diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties index 1a5d62af9bb..d0db58ba98d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties @@ -44,6 +44,7 @@ # 2.9 Standalone Document Declaration SDDeclInvalid = The standalone document declaration value must be \"yes\" or \"no\", not \"{0}\". + SDDeclNameInvalid = The standalone name in XML declaration may be misspelled. # 2.12 Language Identification XMLLangInvalid = The xml:lang attribute value \"{0}\" is an invalid language identifier. # 3. Logical Structures diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java index d1831661f88..e3c24dc8938 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java @@ -21,13 +21,13 @@ package com.sun.org.apache.xerces.internal.impl.xs.models; -import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; -import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; -import com.sun.org.apache.xerces.internal.util.SecurityManager ; -import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; -import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; -import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; +import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; +import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; +import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; /** * @@ -68,7 +68,7 @@ public class CMNodeFactory { // stores defaults for different security holes (maxOccurLimit in current context) if it has // been set on the configuration. - private SecurityManager fSecurityManager = null; + private XMLSecurityManager fSecurityManager = null; /** default constructor */ public CMNodeFactory() { @@ -77,10 +77,10 @@ public class CMNodeFactory { public void reset(XMLComponentManager componentManager){ fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); try { - fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER); + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER); //we are setting the limit of number of nodes to 3times the maxOccur value.. if(fSecurityManager != null){ - maxNodeLimit = fSecurityManager.getMaxOccurNodeLimit() * MULTIPLICITY ; + maxNodeLimit = fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY ; } } catch (XMLConfigurationException e) { @@ -150,8 +150,9 @@ public class CMNodeFactory { if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { - fSecurityManager = (SecurityManager)value; - maxNodeLimit = (fSecurityManager != null) ? fSecurityManager.getMaxOccurNodeLimit() * MULTIPLICITY : 0 ; + fSecurityManager = (XMLSecurityManager)value; + maxNodeLimit = (fSecurityManager != null) ? + fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY : 0 ; return; } if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() && diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java index 3744692c33d..34eaa8457bc 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java @@ -40,6 +40,7 @@ import com.sun.org.apache.xerces.internal.util.DOMUtil; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xs.XSConstants; import java.util.HashMap; @@ -1194,7 +1195,7 @@ public class XSAttributeChecker { if (!optimize) { //Revisit :: IMO this is not right place to check // maxOccurNodeLimit. - int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getMaxOccurNodeLimit(); + int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT); if (max > maxOccurNodeLimit) { reportSchemaFatalError("maxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java index eba1ac0de20..1bfe85c841b 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java @@ -70,7 +70,6 @@ import com.sun.org.apache.xerces.internal.util.DOMUtil; import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXInputSource; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.StAXInputSource; import com.sun.org.apache.xerces.internal.util.StAXLocationWrapper; import com.sun.org.apache.xerces.internal.util.SymbolHash; @@ -78,6 +77,7 @@ import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; @@ -257,7 +257,7 @@ public class XSDHandler { * *

Protected to allow access by any traverser.

*/ - protected SecurityManager fSecureProcessing = null; + protected XMLSecurityManager fSecureProcessing = null; private String fAccessExternalSchema; @@ -3501,7 +3501,7 @@ public class XSDHandler { fSecureProcessing = null; if( componentManager!=null ) { - fSecureProcessing = (SecurityManager) componentManager.getProperty(SECURE_PROCESSING, null); + fSecureProcessing = (XMLSecurityManager) componentManager.getProperty(SECURE_PROCESSING, null); } //set entity resolver diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index 520bc87ea6a..bdb75becd22 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -36,7 +36,7 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer; import com.sun.org.apache.xerces.internal.parsers.DOMParser; -import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -162,7 +162,7 @@ public class DocumentBuilderImpl extends DocumentBuilder // If the secure processing feature is on set a security manager. if (secureProcessing) { - domParser.setProperty(SECURITY_MANAGER, new SecurityManager()); + domParser.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); /** * By default, secure processing is set, no external access is allowed. diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index a57c1543d84..6dad379efba 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -34,8 +34,8 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -151,7 +151,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser // If the secure processing feature is on set a security manager. if (secureProcessing) { - xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager()); + xmlReader.setProperty0(SECURITY_MANAGER, new XMLSecurityManager()); /** * By default, secure processing is set, no external access is allowed. * However, we need to check if it is actively set on the factory since we @@ -413,7 +413,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { try { - setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null); + setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); } catch (SAXNotRecognizedException exc) { // If the property is not supported diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index 95fe7d8d8ec..c560e1e8f54 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -24,7 +24,7 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.parsers.XML11Configuration; -import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; @@ -170,7 +170,7 @@ final class StreamValidatorHelper implements ValidatorHelper { private XMLParserConfiguration initialize() { XML11Configuration config = new XML11Configuration(); if (fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) { - config.setProperty(SECURITY_MANAGER, new SecurityManager()); + config.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); } config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java index 2c3a9842c5e..c4de85d32c7 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java @@ -49,10 +49,10 @@ import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -679,7 +679,7 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements reader = spf.newSAXParser().getXMLReader(); // If this is a Xerces SAX parser, set the security manager if there is one if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) { - SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER); + XMLSecurityManager securityManager = (XMLSecurityManager) fComponentManager.getProperty(SECURITY_MANAGER); if (securityManager != null) { try { reader.setProperty(SECURITY_MANAGER, securityManager); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 763fcdbd29f..1c004dcf4e1 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -41,11 +41,11 @@ import com.sun.org.apache.xerces.internal.util.DOMInputSource; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXInputSource; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.StAXInputSource; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -79,7 +79,7 @@ public final class XMLSchemaFactory extends SchemaFactory { private static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; - /** Property identifier: SecurityManager. */ + /** Property identifier: XMLSecurityManager. */ private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; @@ -108,8 +108,8 @@ public final class XMLSchemaFactory extends SchemaFactory { /** The ErrorHandlerWrapper */ private ErrorHandlerWrapper fErrorHandlerWrapper; - /** The SecurityManager. */ - private SecurityManager fSecurityManager; + /** The XMLSecurityManager. */ + private XMLSecurityManager fSecurityManager; /** The container for the real grammar pool. */ private XMLGrammarPoolWrapper fXMLGrammarPoolWrapper; @@ -137,7 +137,7 @@ public final class XMLSchemaFactory extends SchemaFactory { fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper); // Enable secure processing feature by default - fSecurityManager = new SecurityManager(); + fSecurityManager = new XMLSecurityManager(); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); //by default, the secure feature is set to true, otherwise the default would have been 'file' @@ -365,7 +365,7 @@ public final class XMLSchemaFactory extends SchemaFactory { "jaxp-secureprocessing-feature", null)); } if (value) { - fSecurityManager = new SecurityManager(); + fSecurityManager = new XMLSecurityManager(); fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } else { @@ -404,7 +404,7 @@ public final class XMLSchemaFactory extends SchemaFactory { "ProperyNameNull", null)); } if (name.equals(SECURITY_MANAGER)) { - fSecurityManager = (SecurityManager) object; + fSecurityManager = (XMLSecurityManager) object; fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); return; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index 241d02cbf85..66847d53998 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -39,9 +39,9 @@ import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; @@ -182,7 +182,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private final HashMap fInitProperties = new HashMap(); /** Stores the initial security manager. */ - private final SecurityManager fInitSecurityManager; + private final XMLSecurityManager fInitSecurityManager; // // User Objects @@ -221,7 +221,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (System.getSecurityManager() != null) { _isSecureMode = true; - setProperty(SECURITY_MANAGER, new SecurityManager()); + setProperty(SECURITY_MANAGER, new XMLSecurityManager()); } else { fComponents.put(SECURITY_MANAGER, null); } @@ -242,7 +242,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin // if the secure processing feature is set to true, add a security manager to the configuration Boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); if (Boolean.TRUE.equals(secureProcessing)) { - fInitSecurityManager = new SecurityManager(); + fInitSecurityManager = new XMLSecurityManager(); } else { fInitSecurityManager = null; @@ -308,7 +308,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (_isSecureMode && !value) { throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING); } - setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null); + setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); return; } fConfigUpdated = true; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java index 53ad2a6b605..eea7057417b 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java @@ -25,10 +25,10 @@ import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper; import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolHash; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -1651,7 +1651,7 @@ public abstract class AbstractSAXParser else if (featureId.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { if (state) { if (fConfiguration.getProperty(SECURITY_MANAGER )==null) { - fConfiguration.setProperty(SECURITY_MANAGER, new SecurityManager()); + fConfiguration.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); } } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java index df32bfa41d9..53d4ab4a0ea 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java @@ -23,8 +23,8 @@ package com.sun.org.apache.xerces.internal.parsers; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; /** * This configuration allows Xerces to behave in a security-conscious manner; that is, @@ -106,8 +106,8 @@ public class SecurityConfiguration extends XIncludeAwareParserConfiguration XMLComponentManager parentSettings) { super(symbolTable, grammarPool, parentSettings); - // create the SecurityManager property: - setProperty(SECURITY_MANAGER_PROPERTY, new SecurityManager()); + // create the XMLSecurityManager property: + setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager()); } // (SymbolTable,XMLGrammarPool) } // class SecurityConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java deleted file mode 100644 index dd510b622bc..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 2003 The Apache Software Foundation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * . - */ - -package com.sun.org.apache.xerces.internal.util; -import com.sun.org.apache.xerces.internal.impl.Constants; -import java.security.AccessController; -import java.security.PrivilegedAction; -/** - * This class is a container for parser settings that relate to - * security, or more specifically, it is intended to be used to prevent denial-of-service - * attacks from being launched against a system running Xerces. - * Any component that is aware of a denial-of-service attack that can arise - * from its processing of a certain kind of document may query its Component Manager - * for the property (http://apache.org/xml/properties/security-manager) - * whose value will be an instance of this class. - * If no value has been set for the property, the component should proceed in the "usual" (spec-compliant) - * manner. If a value has been set, then it must be the case that the component in - * question needs to know what method of this class to query. This class - * will provide defaults for all known security issues, but will also provide - * setters so that those values can be tailored by applications that care. - * - * @author Neil Graham, IBM - * - * @version $Id: SecurityManager.java,v 1.5 2010-11-01 04:40:14 joehw Exp $ - */ -public final class SecurityManager { - - // - // Constants - // - - // default value for entity expansion limit - private final static int DEFAULT_ENTITY_EXPANSION_LIMIT = 64000; - - /** Default value of number of nodes created. **/ - private final static int DEFAULT_MAX_OCCUR_NODE_LIMIT = 5000; - - // - // Data - // - - private final static int DEFAULT_ELEMENT_ATTRIBUTE_LIMIT = 10000; - - /** Entity expansion limit. **/ - private int entityExpansionLimit; - - /** W3C XML Schema maxOccurs limit. **/ - private int maxOccurLimit; - - private int fElementAttributeLimit; - // default constructor. Establishes default values for - // all known security holes. - /** - * Default constructor. Establishes default values - * for known security vulnerabilities. - */ - public SecurityManager() { - entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; - maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT ; - fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; - //We are reading system properties only once , - //at the time of creation of this object , - readSystemProperties(); - } - - /** - *

Sets the number of entity expansions that the - * parser should permit in a document.

- * - * @param limit the number of entity expansions - * permitted in a document - */ - public void setEntityExpansionLimit(int limit) { - entityExpansionLimit = limit; - } - - /** - *

Returns the number of entity expansions - * that the parser permits in a document.

- * - * @return the number of entity expansions - * permitted in a document - */ - public int getEntityExpansionLimit() { - return entityExpansionLimit; - } - - /** - *

Sets the limit of the number of content model nodes - * that may be created when building a grammar for a W3C - * XML Schema that contains maxOccurs attributes with values - * other than "unbounded".

- * - * @param limit the maximum value for maxOccurs other - * than "unbounded" - */ - public void setMaxOccurNodeLimit(int limit){ - maxOccurLimit = limit; - } - - /** - *

Returns the limit of the number of content model nodes - * that may be created when building a grammar for a W3C - * XML Schema that contains maxOccurs attributes with values - * other than "unbounded".

- * - * @return the maximum value for maxOccurs other - * than "unbounded" - */ - public int getMaxOccurNodeLimit(){ - return maxOccurLimit; - } - - public int getElementAttrLimit(){ - return fElementAttributeLimit; - } - - public void setElementAttrLimit(int limit){ - fElementAttributeLimit = limit; - } - - private void readSystemProperties(){ - - //TODO: also read SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT - try { - String value = getSystemProperty(Constants.ENTITY_EXPANSION_LIMIT); - if(value != null && !value.equals("")){ - entityExpansionLimit = Integer.parseInt(value); - if (entityExpansionLimit < 0) - entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; - } - else - entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; - }catch(Exception ex){} - - try { - String value = getSystemProperty(Constants.MAX_OCCUR_LIMIT); - if(value != null && !value.equals("")){ - maxOccurLimit = Integer.parseInt(value); - if (maxOccurLimit < 0) - maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; - } - else - maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; - }catch(Exception ex){} - - try { - String value = getSystemProperty(Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT); - if(value != null && !value.equals("")){ - fElementAttributeLimit = Integer.parseInt(value); - if ( fElementAttributeLimit < 0) - fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; - } - else - fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; - - }catch(Exception ex){} - - } - - private String getSystemProperty(final String propName) { - return AccessController.doPrivileged(new PrivilegedAction() { - public String run() { - return System.getProperty(propName); - } - }); - } -} // class SecurityManager diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java index b3d9ed7f925..8e62c1f1d75 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java @@ -173,7 +173,7 @@ public class SymbolTable { for (int i = 0; i < length; i++) { code = code * 37 + symbol.charAt(i); } - return code & 0x7FFFFFF; + return code & 0x7FFFFFFF; } // hash(String):int @@ -194,7 +194,7 @@ public class SymbolTable { for (int i = 0; i < length; i++) { code = code * 37 + buffer[offset + i]; } - return code & 0x7FFFFFF; + return code & 0x7FFFFFFF; } // hash(char[],int,int):int diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java new file mode 100644 index 00000000000..f70aeb7cb21 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xerces.internal.utils; + +import com.sun.org.apache.xerces.internal.impl.Constants; + +/** + * This class manages standard and implementation-specific limitations. + * + */ +public final class XMLSecurityManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + } + + /** + * Limits managed by the security manager + */ + public static enum Limit { + ENTITY_EXPANSION_LIMIT(64000), + MAX_OCCUR_NODE_LIMIT(5000), + ELEMENT_ATTRIBUTE_LIMIT(10000); + + final int defaultValue; + + Limit(int value) { + this.defaultValue = value; + } + + int defaultValue() { + return defaultValue; + } + } + + /** + * Values of the limits as defined in enum Limit + */ + private final int[] limits; + /** + * States of the settings for each limit in limits above + */ + private State[] states = {State.DEFAULT, State.DEFAULT, State.DEFAULT, State.DEFAULT}; + + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLSecurityManager() { + limits = new int[Limit.values().length]; + for (Limit limit : Limit.values()) { + limits[limit.ordinal()] = limit.defaultValue(); + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Sets the limit for a specific type of XML constructs. This can be either + * the size or the number of the constructs. + * + * @param type the type of limitation + * @param state the state of limitation + * @param limit the limit to the type + */ + public void setLimit(Limit limit, State state, int value) { + //only update if it shall override + if (state.compareTo(states[limit.ordinal()]) >= 0) { + limits[limit.ordinal()] = value; + states[limit.ordinal()] = state; + } + } + + /** + * Returns the limit set for the type specified + * + * @param limit the type of limitation + * @return the limit to the type + */ + public int getLimit(Limit limit) { + return limits[limit.ordinal()]; + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + getSystemProperty(Limit.ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT); + getSystemProperty(Limit.MAX_OCCUR_NODE_LIMIT, Constants.MAX_OCCUR_LIMIT); + getSystemProperty(Limit.ELEMENT_ATTRIBUTE_LIMIT, + Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT); + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param limit the type of the property + * @param property the property name + */ + private void getSystemProperty(Limit limit, String property) { + try { + String value = SecuritySupport.getSystemProperty(property); + if (value != null && !value.equals("")) { + limits[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.SYSTEMPROPERTY; + return; + } + + value = SecuritySupport.readJAXPProperty(property); + if (value != null && !value.equals("")) { + limits[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + } + } catch (NumberFormatException e) { + //invalid setting ignored + } + } +} diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java index ba7284609e1..228cd72216d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java @@ -37,7 +37,6 @@ import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; import com.sun.org.apache.xerces.internal.util.HTTPInputSource; import com.sun.org.apache.xerces.internal.util.IntStack; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; @@ -45,6 +44,7 @@ import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -292,7 +292,7 @@ public class XIncludeHandler protected SymbolTable fSymbolTable; protected XMLErrorReporter fErrorReporter; protected XMLEntityResolver fEntityResolver; - protected SecurityManager fSecurityManager; + protected XMLSecurityManager fSecurityManager; /** * comma-delimited list of protocols that are allowed for the purpose * of accessing external dtd or entity references @@ -525,8 +525,8 @@ public class XIncludeHandler // Get security manager. try { - SecurityManager value = - (SecurityManager)componentManager.getProperty( + XMLSecurityManager value = + (XMLSecurityManager)componentManager.getProperty( SECURITY_MANAGER); if (value != null) { @@ -681,7 +681,7 @@ public class XIncludeHandler return; } if (propertyId.equals(SECURITY_MANAGER)) { - fSecurityManager = (SecurityManager)value; + fSecurityManager = (XMLSecurityManager)value; if (fChildConfig != null) { fChildConfig.setProperty(propertyId, value); } diff --git a/jaxp/src/com/sun/xml/internal/stream/Entity.java b/jaxp/src/com/sun/xml/internal/stream/Entity.java index 0ae8228a3be..7bbdf692412 100644 --- a/jaxp/src/com/sun/xml/internal/stream/Entity.java +++ b/jaxp/src/com/sun/xml/internal/stream/Entity.java @@ -248,7 +248,7 @@ public abstract class Entity { public int fBufferSize = DEFAULT_BUFFER_SIZE; /** Default buffer size before we've finished with the XMLDecl: */ - public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 28; + public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64; /** Default internal entity buffer size (1024). */ public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024; From dee5d80756e5d64b1971240bc6f014686d8e824b Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 17 Jul 2013 18:46:28 +0200 Subject: [PATCH 006/152] 8013502: Improve stream factories Reviewed-by: joehw, mullan, lancea --- jaxp/src/javax/xml/stream/FactoryFinder.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/jaxp/src/javax/xml/stream/FactoryFinder.java b/jaxp/src/javax/xml/stream/FactoryFinder.java index 68f4ef21d66..886caa57ee0 100644 --- a/jaxp/src/javax/xml/stream/FactoryFinder.java +++ b/jaxp/src/javax/xml/stream/FactoryFinder.java @@ -253,7 +253,13 @@ class FactoryFinder { // Use the system property first try { - String systemProp = ss.getSystemProperty(factoryId); + + final String systemProp; + if (type.getName().equals(factoryId)) { + systemProp = ss.getSystemProperty(factoryId); + } else { + systemProp = System.getProperty(factoryId); + } if (systemProp != null) { dPrint("found system property, value=" + systemProp); // There's a bug here - because 'cl' is ignored. @@ -262,7 +268,8 @@ class FactoryFinder { } } catch (SecurityException se) { - if (debug) se.printStackTrace(); + throw new FactoryConfigurationError( + "Failed to read factoryId '" + factoryId + "'", se); } // Try read $java.home/lib/stax.properties followed by From 5b17a5cd6dc3ab591cc6a78cc394ed3fcbbb5c09 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 22 Jul 2013 19:38:08 -0700 Subject: [PATCH 007/152] 8017196: Ensure Proxies are handled appropriately Reviewed-by: dfuchs, jrose, jdn, ahgross, chegar --- .../rmi/InvocationHandlerFactoryImpl.java | 14 ++++++++++++-- .../proxy/CompositeInvocationHandlerImpl.java | 11 +++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java index 37a5968d87d..076ed1929ea 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java @@ -43,6 +43,8 @@ import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ; import com.sun.corba.se.spi.orbutil.proxy.DelegateInvocationHandlerImpl ; import com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandler ; import com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl ; +import java.security.AccessController; +import java.security.PrivilegedAction; public class InvocationHandlerFactoryImpl implements InvocationHandlerFactory { @@ -114,24 +116,32 @@ public class InvocationHandlerFactoryImpl implements InvocationHandlerFactory // which extends org.omg.CORBA.Object. This handler delegates all // calls directly to a DynamicStubImpl, which extends // org.omg.CORBA.portable.ObjectImpl. - InvocationHandler dynamicStubHandler = + final InvocationHandler dynamicStubHandler = DelegateInvocationHandlerImpl.create( stub ) ; // Create an invocation handler that handles any remote interface // methods. - InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl( + final InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl( pm, classData, stub ) ; // Create a composite handler that handles the DynamicStub interface // as well as the remote interfaces. final CompositeInvocationHandler handler = new CustomCompositeInvocationHandlerImpl( stub ) ; + + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { handler.addInvocationHandler( DynamicStub.class, dynamicStubHandler ) ; handler.addInvocationHandler( org.omg.CORBA.Object.class, dynamicStubHandler ) ; handler.addInvocationHandler( Object.class, dynamicStubHandler ) ; + return null; + } + }); + // If the method passed to invoke is not from DynamicStub or its superclasses, // it must be from an implemented interface, so we just handle diff --git a/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java b/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java index fb81ceee29c..91aacd5afae 100644 --- a/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java @@ -36,6 +36,7 @@ import java.lang.reflect.InvocationHandler ; import com.sun.corba.se.spi.logging.CORBALogDomains ; import com.sun.corba.se.impl.logging.ORBUtilSystemException ; +import com.sun.corba.se.impl.presentation.rmi.DynamicAccessPermission; public class CompositeInvocationHandlerImpl implements CompositeInvocationHandler @@ -46,11 +47,13 @@ public class CompositeInvocationHandlerImpl implements public void addInvocationHandler( Class interf, InvocationHandler handler ) { + checkAccess(); classToInvocationHandler.put( interf, handler ) ; } public void setDefaultHandler( InvocationHandler handler ) { + checkAccess(); defaultHandler = handler ; } @@ -78,4 +81,12 @@ public class CompositeInvocationHandlerImpl implements return handler.invoke( proxy, method, args ) ; } + + private static final DynamicAccessPermission perm = new DynamicAccessPermission("access"); + private void checkAccess() { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(perm); +} + } } From dd0661e5adf498ddb6857b438c245341ae3b9e04 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 24 Jul 2013 15:18:33 -0700 Subject: [PATCH 008/152] 8016675: Make Javadoc pages more robust Reviewed-by: jlaskey, ksrini --- .../formats/html/markup/HtmlWriter.java | 49 ++++++++++- .../testWindowTitle/TestWindowTitle.java | 82 +++++++++++++++++++ .../sun/javadoc/testWindowTitle/p1/C1.java | 27 ++++++ .../sun/javadoc/testWindowTitle/p2/C2.java | 27 ++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java create mode 100644 langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java create mode 100644 langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 5369733893b..c58e9a66e57 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -290,7 +290,7 @@ public class HtmlWriter { script.addAttr(HtmlAttr.TYPE, "text/javascript"); String scriptCode = "" + DocletConstants.NL; RawHtml scriptContent = new RawHtml(scriptCode); @@ -299,6 +299,53 @@ public class HtmlWriter { return script; } + /** + * Returns a String with escaped special JavaScript characters. + * + * @param s String that needs to be escaped + * @return a valid escaped JavaScript string + */ + private static String escapeJavaScriptChars(String s) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch (ch) { + case '\b': + sb.append("\\b"); + break; + case '\t': + sb.append("\\t"); + break; + case '\n': + sb.append("\\n"); + break; + case '\f': + sb.append("\\f"); + break; + case '\r': + sb.append("\\r"); + break; + case '"': + sb.append("\\\""); + break; + case '\'': + sb.append("\\\'"); + break; + case '\\': + sb.append("\\\\"); + break; + default: + if (ch < 32 || ch >= 127) { + sb.append(String.format("\\u%04X", (int)ch)); + } else { + sb.append(ch); + } + break; + } + } + return sb.toString(); + } + /** * Returns a content tree for the SCRIPT tag for the main page(index.html). * diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java new file mode 100644 index 00000000000..ca4c96ae693 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8016675 + * @summary Test for window title. + * @author Bhavesh Patel + * @library ../lib/ + * @build JavadocTester TestWindowTitle + * @run main TestWindowTitle + */ + +public class TestWindowTitle extends JavadocTester { + + private static final String BUG_ID = "8016675"; + private static final String WIN_TITLE = + "Testing \"Window 'Title'\" with a \\ backslash and a / " + + "forward slash and a \u00e8 unicode char also a tab and also a " + + "\t special character another \u0002 unicode)"; + private static final String[][] TEST = { + {BUG_ID + FS + "overview-summary.html", + "parent.document.title=\"Overview (Testing \\\"Window \\\'Title\\\'\\\" " + + "with a \\\\ backslash and a / forward slash and a \\u00E8 unicode char " + + "also a tab and also a \\t special character another \\u0002 unicode))\";" + }, + }; + private static final String[][] NEG_TEST = { + {BUG_ID + FS + "overview-summary.html", + "parent.document.title=\"Overview (Testing \"Window \'Title\'\" " + + "with a \\ backslash and a / forward slash and a \u00E8 unicode char " + + "also a tab and also a \t special character another \u0002 unicode))\";" + }, + }; + private static final String[] ARGS = new String[]{ + "-d", BUG_ID, "-windowtitle", WIN_TITLE, "-sourcepath", SRC_DIR, "p1", "p2" + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestWindowTitle tester = new TestWindowTitle(); + run(tester, ARGS, TEST, NEG_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java b/langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java new file mode 100644 index 00000000000..239d7a63de0 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p1; + +public class C1 { +} diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java b/langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java new file mode 100644 index 00000000000..7d075a6fd9f --- /dev/null +++ b/langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p2; + +public class C2 { +} From 298bc0138712763e4d5c81ec4920abac454929d2 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 31 Jul 2013 00:37:01 -0700 Subject: [PATCH 009/152] 8014530: Better digital signature processing Reviewed-by: alanb, dfuchs, mullan, lancea --- .../apache/xalan/internal/XalanConstants.java | 121 ++++- .../internal/utils/XMLSecurityManager.java | 449 +++++++++++++++++ .../utils/XMLSecurityPropertyManager.java | 33 ++ .../xalan/internal/xsltc/compiler/Import.java | 2 +- .../internal/xsltc/compiler/Include.java | 2 +- .../xalan/internal/xsltc/compiler/Parser.java | 17 +- .../xalan/internal/xsltc/compiler/XSLTC.java | 11 +- .../xsltc/trax/TemplatesHandlerImpl.java | 4 +- .../xsltc/trax/TransformerFactoryImpl.java | 35 +- .../internal/xsltc/trax/TransformerImpl.java | 4 + .../xalan/internal/xsltc/trax/Util.java | 18 + .../internal/dom/DOMConfigurationImpl.java | 8 + .../xerces/internal/impl/Constants.java | 108 ++++- .../xerces/internal/impl/PropertyManager.java | 24 +- .../impl/XML11NSDocumentScannerImpl.java | 4 +- .../internal/impl/XMLDTDScannerImpl.java | 64 ++- .../impl/XMLDocumentFragmentScannerImpl.java | 61 ++- .../internal/impl/XMLEntityManager.java | 51 +- .../impl/XMLNSDocumentScannerImpl.java | 4 +- .../xerces/internal/impl/XMLScanner.java | 21 +- .../internal/impl/msg/XMLMessages.properties | 10 +- .../impl/xs/models/CMNodeFactory.java | 3 +- .../xs/traversers/XSAttributeChecker.java | 2 +- .../internal/jaxp/DocumentBuilderImpl.java | 29 +- .../xerces/internal/jaxp/SAXParserImpl.java | 94 ++-- .../jaxp/validation/StAXValidatorHelper.java | 14 + .../validation/StreamValidatorHelper.java | 2 + .../jaxp/validation/XMLSchemaFactory.java | 27 +- .../XMLSchemaValidatorComponentManager.java | 49 +- .../xerces/internal/parsers/SAXParser.java | 25 +- .../parsers/SecurityConfiguration.java | 5 +- .../internal/parsers/XML11Configuration.java | 18 +- .../internal/utils/XMLLimitAnalyzer.java | 236 +++++++++ .../internal/utils/XMLSecurityManager.java | 452 ++++++++++++++++-- .../utils/XMLSecurityPropertyManager.java | 35 ++ .../xml/internal/utils/XMLReaderManager.java | 26 +- 36 files changed, 1862 insertions(+), 206 deletions(-) create mode 100644 jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java index ce50626a612..f4a80afacfe 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java @@ -39,6 +39,116 @@ public final class XalanConstants { // // Constants // + //Xerces security manager + public static final String SECURITY_MANAGER = + "http://apache.org/xml/properties/security-manager"; + + // + // Implementation limits: API properties + // + /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */ + public static final String ORACLE_JAXP_PROPERTY_PREFIX = + "http://www.oracle.com/xml/jaxp/properties/"; + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String JDK_ENTITY_EXPANSION_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String JDK_MAX_OCCUR_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String JDK_GENEAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String JDK_XML_NAME_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit"; + /** + * JDK property indicating whether the parser shall print out entity + * count information + * Value: a string "yes" means print, "no" or any other string means not. + */ + public static final String JDK_ENTITY_COUNT_INFO = + ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo"; + + // + // Implementation limits: corresponding System Properties of the above + // API properties + // + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit"; + + //legacy System Properties + public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; + public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; + public final static String MAX_OCCUR_LIMIT = "maxOccurLimit"; + + /** + * A string "yes" that can be used for properties such as getEntityCountInfo + */ + public static final String JDK_YES = "yes"; + // Oracle Feature: /** *

Use Service Mechanism

@@ -51,21 +161,16 @@ public final class XalanConstants { *
  • * {@code false} instruct an object to skip service mechanism and * use the default implementation for that service. - *
  • - * - */ - + * + * + */ public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism"; - /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */ - public static final String ORACLE_JAXP_PROPERTY_PREFIX = - "http://www.oracle.com/xml/jaxp/properties/"; //System Properties corresponding to ACCESS_EXTERNAL_* properties public static final String SP_ACCESS_EXTERNAL_STYLESHEET = "javax.xml.accessExternalStylesheet"; public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD"; - //all access keyword public static final String ACCESS_EXTERNAL_ALL = "all"; diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java new file mode 100644 index 00000000000..99a8e2d5f69 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java @@ -0,0 +1,449 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package com.sun.org.apache.xalan.internal.utils; + +import com.sun.org.apache.xalan.internal.XalanConstants; + + +/** + * This class is not the same as that in Xerces. It is used to manage the + * state of corresponding Xerces properties and pass the values over to + * the Xerces Security Manager. + * + * @author Joe Wang Oracle Corp. + * + */ +public final class XMLSecurityManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + + DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), + JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"), + APIPROPERTY("property"); + + final String literal; + State(String literal) { + this.literal = literal; + } + + String literal() { + return literal; + } + } + + /** + * Limits managed by the security manager + */ + public static enum Limit { + + ENTITY_EXPANSION_LIMIT(XalanConstants.JDK_ENTITY_EXPANSION_LIMIT, + XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000), + MAX_OCCUR_NODE_LIMIT(XalanConstants.JDK_MAX_OCCUR_LIMIT, + XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000), + ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT, + XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000), + TOTAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT, + XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000), + GENEAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_GENEAL_ENTITY_SIZE_LIMIT, + XalanConstants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0), + PARAMETER_ENTITY_SIZE_LIMIT(XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, + XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000); + + final String apiProperty; + final String systemProperty; + final int defaultValue; + final int secureValue; + + Limit(String apiProperty, String systemProperty, int value, int secureValue) { + this.apiProperty = apiProperty; + this.systemProperty = systemProperty; + this.defaultValue = value; + this.secureValue = secureValue; + } + + public boolean equalsAPIPropertyName(String propertyName) { + return (propertyName == null) ? false : apiProperty.equals(propertyName); + } + + public boolean equalsSystemPropertyName(String propertyName) { + return (propertyName == null) ? false : systemProperty.equals(propertyName); + } + + public String apiProperty() { + return apiProperty; + } + + String systemProperty() { + return systemProperty; + } + + int defaultValue() { + return defaultValue; + } + + int secureValue() { + return secureValue; + } + } + + /** + * Map old property names with the new ones + */ + public static enum NameMap { + + ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, + XalanConstants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, + XalanConstants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, + XalanConstants.ELEMENT_ATTRIBUTE_LIMIT); + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + /** + * Values of the properties + */ + private final int[] values; + /** + * States of the settings for each property + */ + private State[] states; + /** + * States that determine if properties are set explicitly + */ + private boolean[] isSet; + + + /** + * Index of the special entityCountInfo property + */ + private int indexEntityCountInfo = 10000; + private String printEntityCountInfo = ""; + + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLSecurityManager() { + this(false); + } + + /** + * Instantiate Security Manager in accordance with the status of + * secure processing + * @param secureProcessing + */ + public XMLSecurityManager(boolean secureProcessing) { + values = new int[Limit.values().length]; + states = new State[Limit.values().length]; + isSet = new boolean[Limit.values().length]; + for (Limit limit : Limit.values()) { + if (secureProcessing) { + values[limit.ordinal()] = limit.secureValue(); + states[limit.ordinal()] = State.FSP; + } else { + values[limit.ordinal()] = limit.defaultValue(); + states[limit.ordinal()] = State.DEFAULT; + } + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Setting FEATURE_SECURE_PROCESSING explicitly + */ + public void setSecureProcessing(boolean secure) { + for (Limit limit : Limit.values()) { + if (secure) { + setLimit(limit.ordinal(), State.FSP, limit.secureValue()); + } else { + setLimit(limit.ordinal(), State.FSP, limit.defaultValue()); + } + } + } + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security manager; false + * if otherwise. + */ + public boolean setLimit(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setLimit(index, state, value); + return true; + } + return false; + } + + /** + * Set the value for a specific limit. + * + * @param limit the limit + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(Limit limit, State state, int value) { + setLimit(limit.ordinal(), state, value); + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, Object value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = (String)value; + } else { + int temp = 0; + try { + temp = Integer.parseInt((String) value); + if (temp < 0) { + temp = 0; + } + } catch (NumberFormatException e) {} + setLimit(index, state, temp); } + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, int value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = XalanConstants.JDK_YES; + } else { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + isSet[index] = true; + } + } + } + + + /** + * Return the value of the specified property. + * + * @param propertyName the property name + * @return the value of the property as a string. If a property is managed + * by this manager, its value shall not be null. + */ + public String getLimitAsString(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getLimitValueByIndex(index); + } + + return null; + } + + /** + * Return the value of a property by its ordinal + * + * @param limit the property + * @return value of a property + */ + public String getLimitValueAsString(Limit limit) { + return Integer.toString(values[limit.ordinal()]); + } + + /** + * Return the value of the specified property + * + * @param limit the property + * @return the value of the property + */ + public int getLimit(Limit limit) { + return values[limit.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * + * @param index the index of a property + * @return value of a property + */ + public int getLimitByIndex(int index) { + return values[index]; + } + /** + * Return the value of a property by its index + * + * @param index the index of a property + * @return limit of a property as a string + */ + public String getLimitValueByIndex(int index) { + if (index == indexEntityCountInfo) { + return printEntityCountInfo; + } + + return Integer.toString(values[index]); + } + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public State getState(Limit limit) { + return states[limit.ordinal()]; + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public String getStateLiteral(Limit limit) { + return states[limit.ordinal()].literal(); + } + + /** + * Get the index by property name + * + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName) { + for (Limit limit : Limit.values()) { + if (limit.equalsAPIPropertyName(propertyName)) { + //internally, ordinal is used as index + return limit.ordinal(); + } + } + //special property to return entity count info + if (propertyName.equals(XalanConstants.JDK_ENTITY_COUNT_INFO)) { + return indexEntityCountInfo; + } + return -1; + } + + /** + * Indicate if a property is set explicitly + * @param index + * @return + */ + public boolean isSet(int index) { + return isSet[index]; + } + + public boolean printEntityCountInfo() { + return printEntityCountInfo.equals(XalanConstants.JDK_YES); + } + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + + for (Limit limit : Limit.values()) { + if (!getSystemProperty(limit, limit.systemProperty())) { + //if system property is not found, try the older form if any + for (NameMap nameMap : NameMap.values()) { + String oldName = nameMap.getOldName(limit.systemProperty()); + if (oldName != null) { + getSystemProperty(limit, oldName); + } + } + } + } + + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the type of the property + * @param sysPropertyName the name of system property + */ + private boolean getSystemProperty(Limit limit, String sysPropertyName) { + try { + String value = SecuritySupport.getSystemProperty(sysPropertyName); + if (value != null && !value.equals("")) { + values[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.SYSTEMPROPERTY; + return true; + } + + value = SecuritySupport.readJAXPProperty(sysPropertyName); + if (value != null && !value.equals("")) { + values[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + return true; + } + } catch (NumberFormatException e) { + //invalid setting + throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty()); + } + return false; + } +} diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java index 5f5501a3434..35dc9a5d04b 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java @@ -93,6 +93,23 @@ public final class XMLSecurityPropertyManager { readSystemProperties(); } + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security property manager; + * false if otherwise. + */ + public boolean setValue(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setValue(index, state, (String)value); + return true; + } + return false; + } + /** * Set the value for a specific property. * @@ -121,6 +138,22 @@ public final class XMLSecurityPropertyManager { states[index] = state; } } + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string + */ + public String getValue(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getValueByIndex(index); + } + + return null; + } + /** * Return the value of the specified property * diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java index fdfbe178d1d..e1971d35c06 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java @@ -86,7 +86,7 @@ final class Import extends TopLevelElement { if (input == null) { docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc); String accessError = SecuritySupport.checkAccess(docToLoad, - xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), + (String)xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), XalanConstants.ACCESS_EXTERNAL_ALL); if (accessError != null) { diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java index 71c129f7cca..5bf12f8dc1b 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java @@ -87,7 +87,7 @@ final class Include extends TopLevelElement { if (input == null) { docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc); String accessError = SecuritySupport.checkAccess(docToLoad, - xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), + (String)xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), XalanConstants.ACCESS_EXTERNAL_ALL); if (accessError != null) { diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java index 3c186a1172b..0903d9a9ef6 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java @@ -28,6 +28,7 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; @@ -487,6 +488,20 @@ public class Parser implements Constants, ContentHandler { } final XMLReader reader = parser.getXMLReader(); + try { + XMLSecurityManager securityManager = + (XMLSecurityManager)_xsltc.getProperty(XalanConstants.SECURITY_MANAGER); + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + reader.setProperty(limit.apiProperty(), securityManager.getLimitValueAsString(limit)); + } + if (securityManager.printEntityCountInfo()) { + parser.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES); + } + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } + return(parse(reader, input)); } catch (ParserConfigurationException e) { @@ -565,7 +580,7 @@ public class Parser implements Constants, ContentHandler { } path = SystemIDResolver.getAbsoluteURI(path); String accessError = SecuritySupport.checkAccess(path, - _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), + (String)_xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), XalanConstants.ACCESS_EXTERNAL_ALL); if (accessError != null) { ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR, diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java index 97fff3bf2e0..10823f14689 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java @@ -44,11 +44,11 @@ import javax.xml.XMLConstants; import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; import com.sun.org.apache.xml.internal.dtm.DTM; -import com.sun.org.apache.xalan.internal.utils.SecuritySupport; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; @@ -146,6 +146,7 @@ public final class XSLTC { */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityManager _xmlSecurityManager; /** * XSLTC compiler constructor @@ -184,12 +185,14 @@ public final class XSLTC { /** * Return allowed protocols for accessing external stylesheet. */ - public String getProperty(String name) { + public Object getProperty(String name) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { return _accessExternalStylesheet; } else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { return _accessExternalDTD; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + return _xmlSecurityManager; } return null; } @@ -197,12 +200,14 @@ public final class XSLTC { /** * Set allowed protocols for accessing external stylesheet. */ - public void setProperty(String name, String value) { + public void setProperty(String name, Object value) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { _accessExternalStylesheet = (String)value; } else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { _accessExternalDTD = (String)value; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + _xmlSecurityManager = (XMLSecurityManager)value; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java index 879c1cb4de0..ff43ca9410f 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java @@ -29,7 +29,7 @@ import javax.xml.transform.Templates; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.sax.TemplatesHandler; - +import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.xsltc.compiler.CompilerException; import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser; import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader; @@ -103,6 +103,8 @@ public class TemplatesHandlerImpl (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)); xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD)); + xsltc.setProperty(XalanConstants.SECURITY_MANAGER, + tfactory.getAttribute(XalanConstants.SECURITY_MANAGER)); if ("true".equals(tfactory.getAttribute(TransformerFactoryImpl.ENABLE_INLINING))) diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index 874892942f9..9b6589d7aa8 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -27,6 +27,7 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.State; @@ -218,13 +219,13 @@ public class TransformerFactoryImpl * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element. */ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT; - /** * protocols allowed for external DTD references in source file and/or stylesheet. */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; private XMLSecurityPropertyManager _xmlSecurityPropertyMgr; + private XMLSecurityManager _xmlSecurityManager; /** * javax.xml.transform.sax.TransformerFactory implementation. @@ -250,6 +251,9 @@ public class TransformerFactoryImpl Property.ACCESS_EXTERNAL_DTD); _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( Property.ACCESS_EXTERNAL_STYLESHEET); + + //Parser's security manager + _xmlSecurityManager = new XMLSecurityManager(true); } /** @@ -311,11 +315,21 @@ public class TransformerFactoryImpl return Boolean.TRUE; else return Boolean.FALSE; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + return _xmlSecurityManager; } - int index = _xmlSecurityPropertyMgr.getIndex(name); - if (index > -1) { - return _xmlSecurityPropertyMgr.getValueByIndex(index); + /** Check to see if the property is managed by the security manager **/ + String propertyValue = (_xmlSecurityManager != null) ? + _xmlSecurityManager.getLimitAsString(name) : null; + if (propertyValue != null) { + return propertyValue; + } else { + propertyValue = (_xmlSecurityPropertyMgr != null) ? + _xmlSecurityPropertyMgr.getValue(name) : null; + if (propertyValue != null) { + return propertyValue; + } } // Throw an exception for all other attributes @@ -419,10 +433,13 @@ public class TransformerFactoryImpl } } - int index = _xmlSecurityPropertyMgr.getIndex(name); - if (index > -1) { - _xmlSecurityPropertyMgr.setValue(index, - State.APIPROPERTY, (String)value); + if (_xmlSecurityManager != null && + _xmlSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + return; + } + + if (_xmlSecurityPropertyMgr != null && + _xmlSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( Property.ACCESS_EXTERNAL_DTD); _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( @@ -473,6 +490,7 @@ public class TransformerFactoryImpl throw new TransformerConfigurationException(err.toString()); } _isNotSecureProcessing = !value; + _xmlSecurityManager.setSecureProcessing(value); // set external access restriction when FSP is explicitly set if (value && XalanConstants.IS_JDK8_OR_ABOVE) { @@ -849,6 +867,7 @@ public class TransformerFactoryImpl if (!_isNotSecureProcessing) xsltc.setSecureProcessing(true); xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet); xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); + xsltc.setProperty(XalanConstants.SECURITY_MANAGER, _xmlSecurityManager); xsltc.init(); // Set a document loader (for xsl:include/import) if defined diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index 7c33c91a8c8..6bf365fe2a7 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java @@ -25,6 +25,7 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -214,6 +215,7 @@ public final class TransformerImpl extends Transformer */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityManager _securityManager; /** * A hashtable to store parameters for the identity transform. These * are not needed during the transformation, but we must keep track of @@ -269,9 +271,11 @@ public final class TransformerImpl extends Transformer _useServicesMechanism = _tfactory.useServicesMechnism(); _accessExternalStylesheet = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET); _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD); + _securityManager = (XMLSecurityManager)_tfactory.getAttribute(XalanConstants.SECURITY_MANAGER); _readerManager = XMLReaderManager.getInstance(_useServicesMechanism); _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing); + _readerManager.setProperty(XalanConstants.SECURITY_MANAGER, _securityManager); //_isIncremental = tfactory._incremental; } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java index b287a351db4..4c6e02936c3 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java @@ -23,6 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; +import com.sun.org.apache.xalan.internal.XalanConstants; import java.io.InputStream; import java.io.Reader; @@ -43,6 +44,7 @@ import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; @@ -151,6 +153,22 @@ public final class Util { + e.getMessage()); } + try { + XMLSecurityManager securityManager = + (XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER); + if (securityManager != null) { + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + reader.setProperty(limit.apiProperty(), + securityManager.getLimitValueAsString(limit)); + } + if (securityManager.printEntityCountInfo()) { + reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES); + } + } + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } xsltc.setXMLReader(reader); }catch (SAXNotRecognizedException snre ) { throw new TransformerConfigurationException diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java index 832724ac586..1e8dcd98817 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java @@ -33,6 +33,7 @@ import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.utils.ObjectFactory; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; @@ -59,6 +60,7 @@ import org.w3c.dom.DOMStringList; import org.w3c.dom.ls.LSResourceResolver; + /** * Xerces implementation of DOMConfiguration that maintains a table of recognized parameters. * @@ -156,6 +158,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + /** Property identifier: Security property manager. */ private static final String XML_SECURITY_PROPERTY_MANAGER = Constants.XML_SECURITY_PROPERTY_MANAGER; @@ -279,6 +284,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings JAXP_SCHEMA_LANGUAGE, DTD_VALIDATOR_FACTORY_PROPERTY, SCHEMA_DV_FACTORY, + SECURITY_MANAGER, XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -313,6 +319,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings fValidationManager = createValidationManager(); setProperty(VALIDATION_MANAGER, fValidationManager); + setProperty(SECURITY_MANAGER, new XMLSecurityManager(true)); + setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java index bcc2a796b08..579622a7270 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java @@ -174,8 +174,6 @@ public final class Constants { /** JAXP schemaSource language: when used internally may include DTD namespace (DOM) */ public static final String SCHEMA_LANGUAGE = "schemaLanguage"; - public static final String SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; - /** JAXP Standard property prefix ("http://javax.xml.XMLConstants/property/"). */ public static final String JAXPAPI_PROPERTY_PREFIX = "http://javax.xml.XMLConstants/property/"; @@ -208,6 +206,107 @@ public final class Constants { */ public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); + // + // Implementation limits: corresponding System Properties of the above + // API properties + // + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String JDK_ENTITY_EXPANSION_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String JDK_MAX_OCCUR_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String JDK_GENEAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String JDK_XML_NAME_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit"; + /** + * JDK property to allow printing out information from the limit analyzer + */ + public static final String JDK_ENTITY_COUNT_INFO = + ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo"; + + // + // Implementation limits: API properties + // + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit"; + + //legacy System Properties + public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; + public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; + public final static String MAX_OCCUR_LIMIT = "maxOccurLimit"; + + /** + * A string "yes" that can be used for properties such as getEntityCountInfo + */ + public static final String JDK_YES = "yes"; + // // DOM features // @@ -443,7 +542,7 @@ public final class Constants { public static final String LOCALE_PROPERTY = "locale"; /** property identifier: security manager. */ - protected static final String SECURITY_MANAGER = + public static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; @@ -511,9 +610,6 @@ public final class Constants { */ public final static String ATTRIBUTE_DECLARED = "ATTRIBUTE_DECLARED"; - public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; - - public final static String MAX_OCCUR_LIMIT = "maxOccurLimit"; /** * {@link org.w3c.dom.TypeInfo} associated with current element/attribute diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index 0f5119d1fb1..8fbf9162409 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -25,6 +25,7 @@ package com.sun.org.apache.xerces.internal.impl; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.xml.internal.stream.StaxEntityResolverWrapper; import java.util.HashMap; @@ -50,12 +51,16 @@ public class PropertyManager { private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning"; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + /** Property identifier: Security property manager. */ private static final String XML_SECURITY_PROPERTY_MANAGER = Constants.XML_SECURITY_PROPERTY_MANAGER; HashMap supportedProps = new HashMap(); + private XMLSecurityManager fSecurityManager; private XMLSecurityPropertyManager fSecurityPropertyMgr; public static final int CONTEXT_READER = 1; @@ -82,6 +87,7 @@ public class PropertyManager { HashMap properties = propertyManager.getProperties(); supportedProps.putAll(properties); + fSecurityManager = (XMLSecurityManager)getProperty(SECURITY_MANAGER); fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER); } @@ -124,6 +130,8 @@ public class PropertyManager { supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false)); supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false)); + fSecurityManager = new XMLSecurityManager(true); + supportedProps.put(SECURITY_MANAGER, fSecurityManager); fSecurityPropertyMgr = new XMLSecurityPropertyManager(); supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); } @@ -142,6 +150,7 @@ public class PropertyManager { */ public boolean containsProperty(String property){ return supportedProps.containsKey(property) || + (fSecurityManager != null && fSecurityManager.getIndex(property) > -1) || (fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ; } @@ -169,12 +178,15 @@ public class PropertyManager { supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; } - int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(property) : -1; - if (index > -1) { - fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - } else { - supportedProps.put(property, value); + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { + //fall back to the existing property manager + supportedProps.put(property, value); + } } if(equivalentProperty != null){ diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java index dbfd46a5d5f..7a826dfcc97 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java @@ -108,6 +108,7 @@ import javax.xml.stream.events.XMLEvent; * @author Elena Litani, IBM * @author Michael Glavassevich, IBM * @author Sunitha Reddy, Sun Microsystems + * @version $Id: XML11NSDocumentScannerImpl.java,v 1.6 2010-11-01 04:39:40 joehw Exp $ */ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl { @@ -236,7 +237,8 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl { // attributes scanAttribute(fAttributes); - if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ + if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) && + fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fElementAttributeLimit) }, diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java index 6c5553c7979..18a9902d1b7 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java @@ -44,6 +44,8 @@ import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.xml.internal.stream.Entity; /** * This class is responsible for scanning the declarations found @@ -66,7 +68,7 @@ import com.sun.org.apache.xerces.internal.impl.Constants; * @author Glenn Marcy, IBM * @author Eric Ye, IBM * - * @version $Id: XMLDTDScannerImpl.java,v 1.7 2007/09/26 12:52:40 ndw Exp $ + * @version $Id: XMLDTDScannerImpl.java,v 1.8 2010-11-01 04:39:41 joehw Exp $ */ public class XMLDTDScannerImpl extends XMLScanner @@ -1545,7 +1547,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { // internal entity if (systemId == null) { - scanEntityValue(fLiteral, fLiteral2); + scanEntityValue(name, isPEDecl, fLiteral, fLiteral2); // since we need it's value anyway, let's snag it so it doesn't get corrupted // if a new load takes place before we store the entity values fStringBuffer.clear(); @@ -1610,7 +1612,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { * the use of scanCharReferenceValue), and fStringBuffer2, anything in them * at the time of calling is lost. */ - protected final void scanEntityValue(XMLString value, + protected final void scanEntityValue(String entityName, boolean isPEDecl, XMLString value, XMLString nonNormalizedValue) throws IOException, XNIException { int quote = fEntityScanner.scanChar(); @@ -1622,10 +1624,20 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { XMLString literal = fString; XMLString literal2 = fString; + int countChar = 0; + if (fLimitAnalyzer == null && fSecurityManager != null) { + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + fLimitAnalyzer.startEntity(entityName); + } + if (fEntityScanner.scanLiteral(quote, fString) != quote) { fStringBuffer.clear(); fStringBuffer2.clear(); do { + if (isPEDecl && fLimitAnalyzer != null) { + checkLimit("%" + entityName, fString.length + countChar); + } + countChar = 0; fStringBuffer.append(fString); fStringBuffer2.append(fString); if (fEntityScanner.skipChar('&')) { @@ -1685,6 +1697,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { } } else { + countChar++; int c = fEntityScanner.peekChar(); if (XMLChar.isHighSurrogate(c)) { scanSurrogates(fStringBuffer2); @@ -1708,9 +1721,17 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { fStringBuffer2.append(fString); literal = fStringBuffer; literal2 = fStringBuffer2; + } else { + if (isPEDecl) { + checkLimit("%" + entityName, literal); + } } value.setValues(literal); nonNormalizedValue.setValues(literal2); + if (fLimitAnalyzer != null) { + fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName); + } + if (!fEntityScanner.skipChar(quote)) { reportFatalError("CloseQuoteMissingInDecl", null); } @@ -2126,6 +2147,43 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { //new SymbolTable()); } + /** + * Add the count of the content buffer and check if the accumulated + * value exceeds the limit + * @param entityName entity name + * @param buffer content buffer + */ + private void checkLimit(String entityName, XMLString buffer) { + checkLimit(entityName, buffer.length); + } + + /** + * Add the count and check limit + * @param entityName entity name + * @param len length of the buffer + */ + private void checkLimit(String entityName, int len) { + if (fLimitAnalyzer == null) { + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + } + fLimitAnalyzer.addValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName, len); + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("MaxEntitySizeLimit", new Object[]{entityName, + fLimitAnalyzer.getValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)}); + } + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("TotalEntitySizeLimit", + new Object[]{fLimitAnalyzer.getTotalValue(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT)}); + } + + } + public DTDGrammar getGrammar(){ return nvGrammarInfo; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index e60c7781156..600527daa93 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -52,10 +52,12 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; -import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.State; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; -import com.sun.xml.internal.stream.Entity; import javax.xml.XMLConstants; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.events.XMLEvent; @@ -213,11 +215,8 @@ public class XMLDocumentFragmentScannerImpl }; private static final char [] cdata = {'[','C','D','A','T','A','['}; - private static final char [] endTag = {'<','/'}; - - //this variable is also used by XMLDocumentScannerImpl in the same package static final char [] xmlDecl = {'<','?','x','m','l'}; - + private static final char [] endTag = {'<','/'}; // debugging /** Debug scanner state. */ @@ -316,6 +315,7 @@ public class XMLDocumentFragmentScannerImpl protected String fDeclaredEncoding = null; /** Xerces Feature: Disallow doctype declaration. */ protected boolean fDisallowDoctype = false; + /** * comma-delimited list of protocols that are allowed for the purpose * of accessing external dtd or entity references @@ -384,7 +384,6 @@ public class XMLDocumentFragmentScannerImpl protected boolean foundBuiltInRefs = false; - protected XMLSecurityManager fSecurityManager = null; //skip element algorithm static final short MAX_DEPTH_LIMIT = 5 ; @@ -572,10 +571,11 @@ public class XMLDocumentFragmentScannerImpl fReportCdataEvent = componentManager.getFeature(Constants.STAX_REPORT_CDATA_EVENT, true); fSecurityManager = (XMLSecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + fElementAttributeLimit = (fSecurityManager != null)? fSecurityManager.getLimit(XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT):0; - fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS, false); Object resolver = componentManager.getProperty(ENTITY_RESOLVER, null); @@ -600,9 +600,6 @@ public class XMLDocumentFragmentScannerImpl //xxx: external entities are supported in Xerces // it would be good to define feature for this case fSupportExternalEntities = true; - fSupportExternalEntities = true; - fSupportExternalEntities = true; - fSupportExternalEntities = true; fReplaceEntityReferences = true; fIsCoalesce = false; @@ -673,6 +670,9 @@ public class XMLDocumentFragmentScannerImpl XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + + fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(Constants.SECURITY_MANAGER); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); } // reset(XMLComponentManager) /** @@ -958,7 +958,6 @@ public class XMLDocumentFragmentScannerImpl // scan decl super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings); - fMarkupDepth--; // pseudo-attribute values @@ -1325,7 +1324,8 @@ public class XMLDocumentFragmentScannerImpl fAddDefaultAttr = true; do { scanAttribute(fAttributes); - if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ + if (fSecurityManager != null && !fSecurityManager.isNoLimit(fElementAttributeLimit) && + fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fAttributes.getLength()) }, @@ -2039,6 +2039,13 @@ public class XMLDocumentFragmentScannerImpl } // getDriverName():String + /** + * Check the protocol used in the systemId against allowed protocols + * + * @param systemId the Id of the URI + * @param allowedProtocols a list of allowed protocols separated by comma + * @return the name of the protocol if rejected, null otherwise + */ String checkAccess(String systemId, String allowedProtocols) throws IOException { String baseSystemId = fEntityScanner.getBaseSystemId(); String expandedSystemId = fEntityManager.expandSystemId(systemId, baseSystemId,fStrictURI); @@ -2836,6 +2843,8 @@ public class XMLDocumentFragmentScannerImpl if(DEBUG){ System.out.println("NOT USING THE BUFFER, STRING = " + fTempString.toString()); } + //check limit before returning event + checkLimit(fContentBuffer); if(dtdGrammarUtil!= null && dtdGrammarUtil.isIgnorableWhiteSpace(fContentBuffer)){ if(DEBUG)System.out.println("Return SPACE EVENT"); return XMLEvent.SPACE; @@ -2934,6 +2943,8 @@ public class XMLDocumentFragmentScannerImpl fLastSectionWasCharacterData = true ; continue; }else{ + //check limit before returning event + checkLimit(fContentBuffer); if(dtdGrammarUtil!= null && dtdGrammarUtil.isIgnorableWhiteSpace(fContentBuffer)){ if(DEBUG)System.out.println("Return SPACE EVENT"); return XMLEvent.SPACE; @@ -3144,6 +3155,30 @@ public class XMLDocumentFragmentScannerImpl } //while loop }//next + /** + * Add the count of the content buffer and check if the accumulated + * value exceeds the limit + * @param buffer content buffer + */ + protected void checkLimit(XMLStringBuffer buffer) { + if (fLimitAnalyzer.isTracking(fCurrentEntityName)) { + fLimitAnalyzer.addValue(Limit.GENEAL_ENTITY_SIZE_LIMIT, fCurrentEntityName, buffer.length); + if (fSecurityManager.isOverLimit(Limit.GENEAL_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("MaxEntitySizeLimit", new Object[]{fCurrentEntityName, + fLimitAnalyzer.getValue(Limit.GENEAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(Limit.GENEAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(Limit.GENEAL_ENTITY_SIZE_LIMIT)}); + } + if (fSecurityManager.isOverLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("TotalEntitySizeLimit", + new Object[]{fLimitAnalyzer.getTotalValue(Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(Limit.TOTAL_ENTITY_SIZE_LIMIT)}); + } + } + } // // Protected methods diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index ac25ae0ccde..59f3aa00e2d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -30,8 +30,9 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.util.*; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; -import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; @@ -174,7 +175,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** access external dtd: file protocol */ static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT; - // recognized features and properties /** Recognized features. */ @@ -307,6 +307,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** used to restrict external access */ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT; + // settings /** @@ -324,10 +325,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { */ protected int fBufferSize = DEFAULT_BUFFER_SIZE; - // stores defaults for entity expansion limit if it has - // been set on the configuration. + /** Security Manager */ protected XMLSecurityManager fSecurityManager = null; + protected XMLLimitAnalyzer fLimitAnalyzer = null; + + protected int entityExpansionIndex; + /** * True if the document entity is standalone. This should really * only be set by the document source (e.g. XMLDocumentScanner). @@ -352,10 +356,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** XML 1.1 entity scanner. */ protected XMLEntityScanner fXML11EntityScanner; - /** entity expansion limit (contains useful data if and only if - fSecurityManager is non-null) */ - protected int fEntityExpansionLimit = 0; - /** count of entities expanded: */ protected int fEntityExpansionCount = 0; @@ -833,6 +833,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fCurrentEntity.setEncodingExternallySpecified(encodingExternallySpecified); fEntityScanner.setCurrentEntity(fCurrentEntity); fResourceIdentifier.setValues(publicId, literalSystemId, baseSystemId, expandedSystemId); + if (fLimitAnalyzer != null) { + fLimitAnalyzer.startEntity(name); + } return encoding; } //setupCurrentEntity(String, XMLInputSource, boolean, boolean): String @@ -1294,10 +1297,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { //expansions exceeds the entity expansion limit, parser will throw fatal error. // Note that this represents the nesting level of open entities. fEntityExpansionCount++; - if( fSecurityManager != null && fEntityExpansionCount > fEntityExpansionLimit ){ - fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, - "EntityExpansionLimitExceeded", - new Object[]{new Integer(fEntityExpansionLimit) }, + if(fLimitAnalyzer != null) { + fLimitAnalyzer.addValue(entityExpansionIndex, name, 1); + } + if( fSecurityManager != null && fSecurityManager.isOverLimit(entityExpansionIndex)){ + fSecurityManager.debugPrint(); + fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"EntityExpansionLimitExceeded", + new Object[]{fSecurityManager.getLimitValueByIndex(entityExpansionIndex)}, XMLErrorReporter.SEVERITY_FATAL_ERROR ); // is there anything better to do than reset the counter? // at least one can envision debugging applications where this might @@ -1361,6 +1367,12 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { if(fCurrentEntity != null){ //close the reader try{ + if (fLimitAnalyzer != null) { + fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.GENEAL_ENTITY_SIZE_LIMIT, fCurrentEntity.name); + if (fCurrentEntity.name.equals("[xml]")) { + fSecurityManager.debugPrint(); + } + } fCurrentEntity.close(); }catch(IOException ex){ throw new XNIException(ex); @@ -1426,6 +1438,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(SECURITY_MANAGER); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + // initialize state //fStandalone = false; fEntities.clear(); @@ -1486,6 +1501,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null); fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null); fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + entityExpansionIndex = fSecurityManager.getIndex(Constants.JDK_ENTITY_EXPANSION_LIMIT); // JAXP 1.5 feature XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); @@ -1506,9 +1523,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { // a class acting as a component manager but not // implementing that interface for whatever reason. public void reset() { - fEntityExpansionLimit = (fSecurityManager != null)? - fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; - // initialize state fStandalone = false; @@ -1645,9 +1659,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { fSecurityManager = (XMLSecurityManager)value; - fEntityExpansionLimit = (fSecurityManager != null)? - fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; - + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); } } @@ -1656,9 +1668,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { { XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value; fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + } } - } - /** * Returns a list of property identifiers that are recognized by * this component. This method may return null if no properties diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java index b0461eb9138..464511c368c 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java @@ -58,6 +58,7 @@ import javax.xml.stream.events.XMLEvent; * @author Neeraj Bajaj, Sun Microsystems * @author Venugopal Rao K, Sun Microsystems * @author Elena Litani, IBM + * @version $Id: XMLNSDocumentScannerImpl.java,v 1.11 2010-11-01 04:39:41 joehw Exp $ */ public class XMLNSDocumentScannerImpl extends XMLDocumentScannerImpl { @@ -251,7 +252,8 @@ public class XMLNSDocumentScannerImpl do { scanAttribute(fAttributes); - if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ + if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) && + fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fAttributes.getLength()) }, diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 9fc489b3e02..70de7869e78 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -32,6 +32,8 @@ import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; +import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLAttributes; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; @@ -106,6 +108,9 @@ public abstract class XMLScanner protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + // debugging /** Debug attribute normalization. */ @@ -159,6 +164,12 @@ public abstract class XMLScanner /** xxx this should be available from EntityManager Entity storage */ protected XMLEntityStorage fEntityStore = null ; + /** Security manager. */ + protected XMLSecurityManager fSecurityManager = null; + + /** Limit analyzer. */ + protected XMLLimitAnalyzer fLimitAnalyzer = null; + // protected data /** event type */ @@ -256,6 +267,7 @@ public abstract class XMLScanner fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE); fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER); + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER); //this step is extra because we have separated the storage of entity fEntityStore = fEntityManager.getEntityStore() ; @@ -293,6 +305,10 @@ public abstract class XMLScanner fEntityManager = (XMLEntityManager)value; } } + + if (propertyId.equals(SECURITY_MANAGER)) { + fSecurityManager = (XMLSecurityManager)value; + } /*else if(propertyId.equals(Constants.STAX_PROPERTIES)){ fStaxProperties = (HashMap)value; //TODO::discuss with neeraj what are his thoughts on passing properties. @@ -352,6 +368,8 @@ public abstract class XMLScanner fEntityManager = (XMLEntityManager)propertyManager.getProperty(ENTITY_MANAGER); fEntityStore = fEntityManager.getEntityStore() ; fEntityScanner = (XMLEntityScanner)fEntityManager.getEntityScanner() ; + fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(SECURITY_MANAGER); + //fEntityManager.reset(); // DTD preparsing defaults: fValidation = false; @@ -510,8 +528,9 @@ public abstract class XMLScanner sawSpace = fEntityScanner.skipSpaces(); } // restore original literal value - if(currLiteral) + if(currLiteral) { currEnt.literal = true; + } // REVISIT: should we remove this error reporting? if (scanningTextDecl && state != STATE_DONE) { reportFatalError("MorePseudoAttributes", null); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties index d0db58ba98d..200b904b105 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties @@ -293,8 +293,10 @@ InvalidCharInLiteral=InvalidCharInLiteral -#Application can set the limit of number of entities that should be expanded by the parser. -EntityExpansionLimitExceeded=The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the application. +# Implementation limits + EntityExpansionLimitExceeded=JAXP00010001: The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the JDK. + ElementAttributeLimit=JAXP00010002: Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the JDK. + MaxEntitySizeLimit=JAXP00010003: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\". + TotalEntitySizeLimit=JAXP00010004: The accumulated size \"{0}\" of entities exceeded the \"{1}\" limit set by \"{2}\". + MaxXMLNameLimit=JAXP00010005: The name \"{0}\" exceeded the \"{1}\" limit set by \"{2}\". -# Application can set the limit of number of attributes of entity that should be expanded by the parser. -ElementAttributeLimit= Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the application. diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java index e3c24dc8938..6aa06b8828d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java @@ -109,7 +109,8 @@ public class CMNodeFactory { } public void nodeCountCheck(){ - if( fSecurityManager != null && nodeCount++ > maxNodeLimit){ + if( fSecurityManager != null && !fSecurityManager.isNoLimit(maxNodeLimit) && + nodeCount++ > maxNodeLimit){ if(DEBUG){ System.out.println("nodeCount = " + nodeCount ) ; System.out.println("nodeLimit = " + maxNodeLimit ) ; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java index 34eaa8457bc..f9eea6a4dc4 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java @@ -1196,7 +1196,7 @@ public class XSAttributeChecker { //Revisit :: IMO this is not right place to check // maxOccurNodeLimit. int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT); - if (max > maxOccurNodeLimit) { + if (max > maxOccurNodeLimit && !fSchemaHandler.fSecureProcessing.isNoLimit(maxOccurNodeLimit)) { reportSchemaFatalError("maxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element); // reset max values in case processing continues on error diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index f19f81dbef8..e73c12d24da 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -46,7 +46,6 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; -import javax.xml.XMLConstants; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; @@ -125,6 +124,7 @@ public class DocumentBuilderImpl extends DocumentBuilder /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; + private XMLSecurityManager fSecurityManager; private XMLSecurityPropertyManager fSecurityPropertyMgr; DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features) @@ -173,10 +173,10 @@ public class DocumentBuilderImpl extends DocumentBuilder fSecurityPropertyMgr = new XMLSecurityPropertyManager(); domParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); - // If the secure processing feature is on set a security manager. - if (secureProcessing) { - domParser.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); + fSecurityManager = new XMLSecurityManager(secureProcessing); + domParser.setProperty(SECURITY_MANAGER, fSecurityManager); + if (secureProcessing) { /** * If secure processing is explicitly set on the factory, the * access properties will be set unless the corresponding @@ -250,9 +250,9 @@ public class DocumentBuilderImpl extends DocumentBuilder String feature = (String) entry.getKey(); boolean value = ((Boolean) entry.getValue()).booleanValue(); domParser.setFeature(feature, value); - } } } + } /** * Set any DocumentBuilderFactory attributes of our underlying DOMParser @@ -303,14 +303,17 @@ public class DocumentBuilderImpl extends DocumentBuilder } } } else { - int index = fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)val); - } else { - // Let Xerces code handle the property - domParser.setProperty(name, val); - } + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, val)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, val)) { + //fall back to the existing property manager + domParser.setProperty(name, val); + } + } + } } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index a60d1e5085d..d95b1ca8851 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -112,7 +112,8 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; - private XMLSecurityPropertyManager fSecurityPropertyMgr; + private final XMLSecurityManager fSecurityManager; + private final XMLSecurityPropertyManager fSecurityPropertyMgr; /** * Create a SAX parser with the associated features @@ -130,8 +131,10 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing) throws SAXException { + fSecurityManager = new XMLSecurityManager(secureProcessing); + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader - xmlReader = new JAXPSAXParser(this); + xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager); // JAXP "namespaceAware" == SAX Namespaces feature // Note: there is a compatibility problem here with default values: @@ -150,12 +153,11 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser xmlReader.setFeature0(XINCLUDE_FEATURE, true); } - fSecurityPropertyMgr = new XMLSecurityPropertyManager(); xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); - // If the secure processing feature is on set a security manager. + xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager); + if (secureProcessing) { - xmlReader.setProperty0(SECURITY_MANAGER, new XMLSecurityManager()); /** * By default, secure processing is set, no external access is allowed. * However, we need to check if it is actively set on the factory since we @@ -163,6 +165,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser * the default value */ if (features != null) { + Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); if (temp != null) { boolean value = ((Boolean) temp).booleanValue(); @@ -397,14 +400,43 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser private final HashMap fInitFeatures = new HashMap(); private final HashMap fInitProperties = new HashMap(); private final SAXParserImpl fSAXParser; + private XMLSecurityManager fSecurityManager; + private XMLSecurityPropertyManager fSecurityPropertyMgr; public JAXPSAXParser() { - this(null); + this(null, null, null); } - JAXPSAXParser(SAXParserImpl saxParser) { + JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr, + XMLSecurityManager securityManager) { super(); fSAXParser = saxParser; + fSecurityManager = securityManager; + fSecurityPropertyMgr = securityPropertyMgr; + /** + * This class may be used directly. So initialize the security manager if + * it is null. + */ + if (fSecurityManager == null) { + fSecurityManager = new XMLSecurityManager(true); + try { + super.setProperty(SECURITY_MANAGER, fSecurityManager); + } catch (SAXException e) { + throw new UnsupportedOperationException( + SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), + "property-not-recognized", new Object [] {SECURITY_MANAGER}), e); + } + } + if (fSecurityPropertyMgr == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + try { + super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + } catch (SAXException e) { + throw new UnsupportedOperationException( + SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), + "property-not-recognized", new Object [] {SECURITY_MANAGER}), e); + } + } } /** @@ -420,7 +452,8 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { try { - setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); + fSecurityManager.setSecureProcessing(value); + setProperty(SECURITY_MANAGER, fSecurityManager); } catch (SAXNotRecognizedException exc) { // If the property is not supported @@ -456,13 +489,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser throw new NullPointerException(); } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - try { - return (super.getProperty(SECURITY_MANAGER) != null); - } - // If the property is not supported the value must be false. - catch (SAXException exc) { - return false; - } + return fSecurityManager.isSecureProcessing(); } return super.getFeature(name); } @@ -541,17 +568,21 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser if (fSAXParser != null && fSAXParser.fSchemaValidator != null) { setSchemaValidatorProperty(name, value); } - /** Check to see if the property is managed by the property manager **/ - int index = fSAXParser.fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - fSAXParser.fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - } else { - if (!fInitProperties.containsKey(name)) { - fInitProperties.put(name, super.getProperty(name)); + + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { + //fall back to the existing property manager + if (!fInitProperties.containsKey(name)) { + fInitProperties.put(name, super.getProperty(name)); + } + super.setProperty(name, value); } - super.setProperty(name, value); } + } public synchronized Object getProperty(String name) @@ -564,9 +595,18 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser // JAXP 1.2 support return fSAXParser.schemaLanguage; } - int index = fSAXParser.fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - return fSAXParser.fSecurityPropertyMgr.getValueByIndex(index); + + /** Check to see if the property is managed by the security manager **/ + String propertyValue = (fSecurityManager != null) ? + fSecurityManager.getLimitAsString(name) : null; + if (propertyValue != null) { + return propertyValue; + } else { + propertyValue = (fSecurityPropertyMgr != null) ? + fSecurityPropertyMgr.getValue(name) : null; + if (propertyValue != null) { + return propertyValue; + } } return super.getProperty(name); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java index f398e037d18..5af27e26fc1 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java @@ -26,6 +26,7 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import java.io.IOException; import javax.xml.transform.Result; @@ -73,6 +74,19 @@ public final class StAXValidatorHelper implements ValidatorHelper { SAXTransformerFactory tf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? (SAXTransformerFactory)SAXTransformerFactory.newInstance() : (SAXTransformerFactory) TransformerFactory.newInstance(DEFAULT_TRANSFORMER_IMPL, StAXValidatorHelper.class.getClassLoader()); + XMLSecurityManager securityManager = (XMLSecurityManager)fComponentManager.getProperty(Constants.SECURITY_MANAGER); + if (securityManager != null) { + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + if (securityManager.isSet(limit.ordinal())){ + tf.setAttribute(limit.apiProperty(), + securityManager.getLimitValueAsString(limit)); + } + } + if (securityManager.printEntityCountInfo()) { + tf.setAttribute(Constants.JDK_ENTITY_COUNT_INFO, "yes"); + } + } + identityTransformer1 = tf.newTransformer(); identityTransformer2 = tf.newTransformerHandler(); } catch (TransformerConfigurationException e) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index bb1694c5160..d6c04fd984a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -189,6 +189,8 @@ final class StreamValidatorHelper implements ValidatorHelper { config.setDTDContentModelHandler(null); config.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, fComponentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER)); + config.setProperty(Constants.SECURITY_MANAGER, + fComponentManager.getProperty(Constants.SECURITY_MANAGER)); fConfiguration = new SoftReference(config); return config; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 3a59da745ed..34eba4c4791 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -107,7 +107,7 @@ public final class XMLSchemaFactory extends SchemaFactory { /** The ErrorHandlerWrapper */ private ErrorHandlerWrapper fErrorHandlerWrapper; - /** The XMLSecurityManager. */ + /** The SecurityManager. */ private XMLSecurityManager fSecurityManager; /** The Security property manager. */ @@ -141,7 +141,7 @@ public final class XMLSchemaFactory extends SchemaFactory { fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper); // Enable secure processing feature by default - fSecurityManager = new XMLSecurityManager(); + fSecurityManager = new XMLSecurityManager(true); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); fSecurityPropertyMgr = new XMLSecurityPropertyManager(); @@ -301,7 +301,7 @@ public final class XMLSchemaFactory extends SchemaFactory { "FeatureNameNull", null)); } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - return (fSecurityManager != null); + return (fSecurityManager != null && fSecurityManager.isSecureProcessing()); } try { return fXMLSchemaLoader.getFeature(name); @@ -365,17 +365,15 @@ public final class XMLSchemaFactory extends SchemaFactory { SAXMessageFormatter.formatMessage(null, "jaxp-secureprocessing-feature", null)); } - if (value) { - fSecurityManager = new XMLSecurityManager(); + fSecurityManager.setSecureProcessing(value); + if (value) { if (Constants.IS_JDK8_OR_ABOVE) { fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } - } else { - fSecurityManager = null; } fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); @@ -420,12 +418,15 @@ public final class XMLSchemaFactory extends SchemaFactory { "property-not-supported", new Object [] {name})); } try { - int index = fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)object); - } else { - fXMLSchemaLoader.setProperty(name, object); + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, object)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, object)) { + //fall back to the existing property manager + fXMLSchemaLoader.setProperty(name, object); + } } } catch (XMLConfigurationException e) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index 8b006fa7361..dcbbabd4d4a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -181,7 +181,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private final HashMap fInitProperties = new HashMap(); /** Stores the initial security manager. */ - private final XMLSecurityManager fInitSecurityManager; + private XMLSecurityManager fInitSecurityManager; /** Stores the initial security property manager. */ private final XMLSecurityPropertyManager fSecurityPropertyMgr; @@ -221,12 +221,6 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fComponents.put(ENTITY_RESOLVER, null); fComponents.put(ERROR_HANDLER, null); - if (System.getSecurityManager() != null) { - _isSecureMode = true; - setProperty(SECURITY_MANAGER, new XMLSecurityManager()); - } else { - fComponents.put(SECURITY_MANAGER, null); - } fComponents.put(SYMBOL_TABLE, new SymbolTable()); // setup grammar pool @@ -241,15 +235,21 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin addRecognizedParamsAndSetDefaults(fErrorReporter, grammarContainer); addRecognizedParamsAndSetDefaults(fSchemaValidator, grammarContainer); - // if the secure processing feature is set to true, add a security manager to the configuration - Boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); - if (Boolean.TRUE.equals(secureProcessing)) { - fInitSecurityManager = new XMLSecurityManager(); + boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); + if (System.getSecurityManager() != null) { + _isSecureMode = true; + secureProcessing = true; } - else { - fInitSecurityManager = null; + + fInitSecurityManager = (XMLSecurityManager) + grammarContainer.getProperty(SECURITY_MANAGER); + if (fInitSecurityManager != null ) { + fInitSecurityManager.setSecureProcessing(secureProcessing); + } else { + fInitSecurityManager = new XMLSecurityManager(secureProcessing); } - fComponents.put(SECURITY_MANAGER, fInitSecurityManager); + + setProperty(SECURITY_MANAGER, fInitSecurityManager); //pass on properties set on SchemaFactory fSecurityPropertyMgr = (XMLSecurityPropertyManager) @@ -281,7 +281,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin return FeatureState.is(fUseGrammarPoolOnly); } else if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) { - return FeatureState.is(getProperty(SECURITY_MANAGER) != null); + return FeatureState.is(fInitSecurityManager.isSecureProcessing()); } else if (SCHEMA_ELEMENT_DEFAULT.equals(featureId)) { return FeatureState.is(true); //pre-condition: VALIDATION and SCHEMA_VALIDATION are always true @@ -311,7 +311,9 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (_isSecureMode && !value) { throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING); } - setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); + + fInitSecurityManager.setSecureProcessing(value); + setProperty(SECURITY_MANAGER, fInitSecurityManager); if (value && Constants.IS_JDK8_OR_ABOVE) { fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, @@ -390,10 +392,19 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fComponents.put(propertyId, value); return; } - if (!fInitProperties.containsKey(propertyId)) { - fInitProperties.put(propertyId, super.getProperty(propertyId)); + //check if the property is managed by security manager + if (fInitSecurityManager == null || + !fInitSecurityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(propertyId, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { + //fall back to the existing property manager + if (!fInitProperties.containsKey(propertyId)) { + fInitProperties.put(propertyId, super.getProperty(propertyId)); + } + super.setProperty(propertyId, value); + } } - super.setProperty(propertyId, value); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java index cf9e9a79f92..8432b54541e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java @@ -22,6 +22,7 @@ package com.sun.org.apache.xerces.internal.parsers; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; @@ -76,6 +77,8 @@ public class SAXParser XMLGRAMMAR_POOL, }; + XMLSecurityManager securityManager; + XMLSecurityPropertyManager securityPropertyManager; // // Constructors // @@ -129,18 +132,30 @@ public class SAXParser */ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { - XMLSecurityPropertyManager spm = new XMLSecurityPropertyManager(); - int index = spm.getIndex(name); + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } + int index = securityPropertyManager.getIndex(name); if (index > -1) { /** * this is a direct call to this parser, not a subclass since * internally the support of this property is done through * XMLSecurityPropertyManager */ - spm.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, spm); + securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); } else { - super.setProperty(name, value); + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + + //check if the property is managed by security manager + if (securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + super.setProperty(Constants.SECURITY_MANAGER, securityManager); + } else { + super.setProperty(name, value); + } + } } } // class SAXParser diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java index 53d4ab4a0ea..65c85d164ca 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java @@ -44,6 +44,7 @@ import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; * * @author Neil Graham, IBM * + * @version $Id: SecurityConfiguration.java,v 1.6 2010-11-01 04:40:09 joehw Exp $ */ public class SecurityConfiguration extends XIncludeAwareParserConfiguration { @@ -106,8 +107,8 @@ public class SecurityConfiguration extends XIncludeAwareParserConfiguration XMLComponentManager parentSettings) { super(symbolTable, grammarPool, parentSettings); - // create the XMLSecurityManager property: - setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager()); + // create the SecurityManager property: + setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager(true)); } // (SymbolTable,XMLGrammarPool) } // class SecurityConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 62dec4a54e7..3f22807e37e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -20,6 +20,12 @@ package com.sun.org.apache.xerces.internal.parsers; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import javax.xml.XMLConstants; + import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl; @@ -46,6 +52,7 @@ import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; @@ -63,11 +70,6 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import javax.xml.XMLConstants; /** * This class is the configuration used to parse XML 1.0 and XML 1.1 documents. @@ -278,6 +280,8 @@ public class XML11Configuration extends ParserConfigurationSettings private static final String XML_SECURITY_PROPERTY_MANAGER = Constants.XML_SECURITY_PROPERTY_MANAGER; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; // debugging @@ -483,7 +487,6 @@ public class XML11Configuration extends ParserConfigurationSettings PARSER_SETTINGS, XMLConstants.FEATURE_SECURE_PROCESSING }; - addRecognizedFeatures(recognizedFeatures); // set state for default features fFeatures.put(VALIDATION, Boolean.FALSE); @@ -531,6 +534,7 @@ public class XML11Configuration extends ParserConfigurationSettings SCHEMA_NONS_LOCATION, LOCALE, SCHEMA_DV_FACTORY, + SECURITY_MANAGER, XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -581,6 +585,8 @@ public class XML11Configuration extends ParserConfigurationSettings fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); + fProperties.put(SECURITY_MANAGER, new XMLSecurityManager(true)); + // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { XMLMessageFormatter xmft = new XMLMessageFormatter(); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java new file mode 100644 index 00000000000..41724b6c50d --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java @@ -0,0 +1,236 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package com.sun.org.apache.xerces.internal.utils; + +import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit; +import java.util.Formatter; +import java.util.HashMap; +import java.util.Map; + +/** + * A helper for analyzing entity expansion limits + * + * @author Joe Wang Oracle Corp. + * + */ +public final class XMLLimitAnalyzer { + + /** + * Map old property names with the new ones + */ + public static enum NameMap { + ENTITY_EXPANSION_LIMIT(Constants.SP_ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(Constants.SP_MAX_OCCUR_LIMIT, Constants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, Constants.ELEMENT_ATTRIBUTE_LIMIT); + + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + + private XMLSecurityManager securityManager; + /** + * Max value accumulated for each property + */ + private final int[] values; + /** + * Names of the entities corresponding to their max values + */ + private final String[] names; + /** + * Total value of accumulated entities + */ + private final int[] totalValue; + + /** + * Maintain values of the top 10 elements in the process of parsing + */ + private final Map[] caches; + + private String entityStart, entityEnd; + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLLimitAnalyzer(XMLSecurityManager securityManager) { + this.securityManager = securityManager; + values = new int[Limit.values().length]; + totalValue = new int[Limit.values().length]; + names = new String[Limit.values().length]; + caches = new Map[Limit.values().length]; + } + + /** + * Add the value to the current max count for the specified property + * To find the max value of all entities, set no limit + * + * @param limit the type of the property + * @param entityName the name of the entity + * @param value the value of the entity + */ + public void addValue(Limit limit, String entityName, int value) { + addValue(limit.ordinal(), entityName, value); + } + + /** + * Add the value to the current count by the index of the property + * @param index the index of the property + * @param entityName the name of the entity + * @param value the value of the entity + */ + public void addValue(int index, String entityName, int value) { + if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() || + index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal()) { + totalValue[index] += value; + return; + } + + Map cache; + if (caches[index] == null) { + cache = new HashMap(10); + caches[index] = cache; + } else { + cache = caches[index]; + } + + int accumulatedValue = value; + if (cache.containsKey(entityName)) { + accumulatedValue += cache.get(entityName).intValue(); + cache.put(entityName, Integer.valueOf(accumulatedValue)); + } else { + cache.put(entityName, Integer.valueOf(value)); + } + + if (accumulatedValue > values[index]) { + values[index] = accumulatedValue; + names[index] = entityName; + } + + + if (index == Limit.GENEAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.PARAMETER_ENTITY_SIZE_LIMIT.ordinal()) { + totalValue[Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()] += value; + } + } + + /** + * Return the value of the current max count for the specified property + * + * @param limit the property + * @return the value of the property + */ + public int getValue(Limit limit) { + return values[limit.ordinal()]; + } + + public int getValue(int index) { + return values[index]; + } + /** + * Return the total value accumulated so far + * + * @param limit the property + * @return the accumulated value of the property + */ + public int getTotalValue(Limit limit) { + return totalValue[limit.ordinal()]; + } + + public int getTotalValue(int index) { + return totalValue[index]; + } + /** + * Return the current max value (count or length) by the index of a property + * @param index the index of a property + * @return count of a property + */ + public int getValueByIndex(int index) { + return values[index]; + } + + public void startEntity(String name) { + entityStart = name; + } + + public boolean isTracking(String name) { + return entityStart.equals(name); + } + /** + * Stop tracking the entity + * @param limit the limit property + * @param name the name of an entity + */ + public void endEntity(Limit limit, String name) { + entityStart = ""; + Map cache = caches[limit.ordinal()]; + if (cache != null) { + cache.remove(name); + } + } + + public void debugPrint() { + Formatter formatter = new Formatter(); + System.out.println(formatter.format("%30s %15s %15s %15s %30s", + "Property","Limit","Total size","Size","Entity Name")); + + for (Limit limit : Limit.values()) { + formatter = new Formatter(); + System.out.println(formatter.format("%30s %15d %15d %15d %30s", + limit.name(), + securityManager.getLimit(limit), + totalValue[limit.ordinal()], + values[limit.ordinal()], + names[limit.ordinal()])); + } + } +} diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java index f70aeb7cb21..1ddb651d6df 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java @@ -40,108 +40,482 @@ public final class XMLSecurityManager { */ public static enum State { //this order reflects the overriding order - DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + + DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), + JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"), + APIPROPERTY("property"); + + final String literal; + State(String literal) { + this.literal = literal; + } + + String literal() { + return literal; + } } /** * Limits managed by the security manager */ public static enum Limit { - ENTITY_EXPANSION_LIMIT(64000), - MAX_OCCUR_NODE_LIMIT(5000), - ELEMENT_ATTRIBUTE_LIMIT(10000); + ENTITY_EXPANSION_LIMIT(Constants.JDK_ENTITY_EXPANSION_LIMIT, Constants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000), + MAX_OCCUR_NODE_LIMIT(Constants.JDK_MAX_OCCUR_LIMIT, Constants.SP_MAX_OCCUR_LIMIT, 0, 5000), + ELEMENT_ATTRIBUTE_LIMIT(Constants.JDK_ELEMENT_ATTRIBUTE_LIMIT, Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000), + TOTAL_ENTITY_SIZE_LIMIT(Constants.JDK_TOTAL_ENTITY_SIZE_LIMIT, Constants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000), + GENEAL_ENTITY_SIZE_LIMIT(Constants.JDK_GENEAL_ENTITY_SIZE_LIMIT, Constants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0), + PARAMETER_ENTITY_SIZE_LIMIT(Constants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, Constants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000); + + final String apiProperty; + final String systemProperty; final int defaultValue; + final int secureValue; - Limit(int value) { + Limit(String apiProperty, String systemProperty, int value, int secureValue) { + this.apiProperty = apiProperty; + this.systemProperty = systemProperty; this.defaultValue = value; + this.secureValue = secureValue; + } + + public boolean equalsAPIPropertyName(String propertyName) { + return (propertyName == null) ? false : apiProperty.equals(propertyName); + } + + public boolean equalsSystemPropertyName(String propertyName) { + return (propertyName == null) ? false : systemProperty.equals(propertyName); + } + + public String apiProperty() { + return apiProperty; + } + + String systemProperty() { + return systemProperty; } int defaultValue() { return defaultValue; } + + int secureValue() { + return secureValue; + } } /** - * Values of the limits as defined in enum Limit + * Map old property names with the new ones */ - private final int[] limits; + public static enum NameMap { + + ENTITY_EXPANSION_LIMIT(Constants.SP_ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(Constants.SP_MAX_OCCUR_LIMIT, Constants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, Constants.ELEMENT_ATTRIBUTE_LIMIT); + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + private static final int NO_LIMIT = 0; /** - * States of the settings for each limit in limits above + * Values of the properties */ - private State[] states = {State.DEFAULT, State.DEFAULT, State.DEFAULT, State.DEFAULT}; + private final int[] values; + /** + * States of the settings for each property + */ + private State[] states; + /** + * Flag indicating if secure processing is set + */ + boolean secureProcessing; + + /** + * States that determine if properties are set explicitly + */ + private boolean[] isSet; + + + private XMLLimitAnalyzer limitAnalyzer; + /** + * Index of the special entityCountInfo property + */ + private int indexEntityCountInfo = 10000; + private String printEntityCountInfo = ""; /** * Default constructor. Establishes default values for known security * vulnerabilities. */ public XMLSecurityManager() { - limits = new int[Limit.values().length]; + this(false); + } + + /** + * Instantiate Security Manager in accordance with the status of + * secure processing + * @param secureProcessing + */ + public XMLSecurityManager(boolean secureProcessing) { + limitAnalyzer = new XMLLimitAnalyzer(this); + values = new int[Limit.values().length]; + states = new State[Limit.values().length]; + isSet = new boolean[Limit.values().length]; + this.secureProcessing = secureProcessing; for (Limit limit : Limit.values()) { - limits[limit.ordinal()] = limit.defaultValue(); + if (secureProcessing) { + values[limit.ordinal()] = limit.secureValue; + states[limit.ordinal()] = State.FSP; + } else { + values[limit.ordinal()] = limit.defaultValue(); + states[limit.ordinal()] = State.DEFAULT; + } } //read system properties or jaxp.properties readSystemProperties(); } /** - * Sets the limit for a specific type of XML constructs. This can be either - * the size or the number of the constructs. - * - * @param type the type of limitation - * @param state the state of limitation - * @param limit the limit to the type + * Setting FEATURE_SECURE_PROCESSING explicitly */ - public void setLimit(Limit limit, State state, int value) { - //only update if it shall override - if (state.compareTo(states[limit.ordinal()]) >= 0) { - limits[limit.ordinal()] = value; - states[limit.ordinal()] = state; + public void setSecureProcessing(boolean secure) { + secureProcessing = secure; + for (Limit limit : Limit.values()) { + if (secure) { + setLimit(limit.ordinal(), State.FSP, limit.secureValue()); + } else { + setLimit(limit.ordinal(), State.FSP, limit.defaultValue()); + } } } /** - * Returns the limit set for the type specified + * Return the state of secure processing + * @return the state of secure processing + */ + public boolean isSecureProcessing() { + return secureProcessing; + } + + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security manager; false + * if otherwise. + */ + public boolean setLimit(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setLimit(index, state, value); + return true; + } + return false; + } + + /** + * Set the value for a specific limit. * - * @param limit the type of limitation - * @return the limit to the type + * @param limit the limit + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(Limit limit, State state, int value) { + setLimit(limit.ordinal(), state, value); + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, Object value) { + if (index == indexEntityCountInfo) { + printEntityCountInfo = (String)value; + } else { + int temp = 0; + try { + temp = Integer.parseInt((String) value); + if (temp < 0) { + temp = 0; + } + } catch (NumberFormatException e) {} + setLimit(index, state, temp); + } + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, int value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = Constants.JDK_YES; + } else { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + isSet[index] = true; + } + } + } + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string. If a property is managed + * by this manager, its value shall not be null. + */ + public String getLimitAsString(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getLimitValueByIndex(index); + } + + return null; + } + /** + * Return the value of the specified property + * + * @param limit the property + * @return the value of the property */ public int getLimit(Limit limit) { - return limits[limit.ordinal()]; + return values[limit.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * + * @param limit the property + * @return value of a property + */ + public String getLimitValueAsString(Limit limit) { + return Integer.toString(values[limit.ordinal()]); + } + + /** + * Return the value of a property by its ordinal + * + * @param index the index of a property + * @return limit of a property as a string + */ + public String getLimitValueByIndex(int index) { + if (index == indexEntityCountInfo) { + return printEntityCountInfo; + } + + return Integer.toString(values[index]); + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public State getState(Limit limit) { + return states[limit.ordinal()]; + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public String getStateLiteral(Limit limit) { + return states[limit.ordinal()].literal(); + } + + /** + * Get the index by property name + * + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName) { + for (Limit limit : Limit.values()) { + if (limit.equalsAPIPropertyName(propertyName)) { + //internally, ordinal is used as index + return limit.ordinal(); + } + } + //special property to return entity count info + if (propertyName.equals(Constants.JDK_ENTITY_COUNT_INFO)) { + return indexEntityCountInfo; + } + return -1; + } + + /** + * Check if there's no limit defined by the Security Manager + * @param limit + * @return + */ + public boolean isNoLimit(int limit) { + return limit==NO_LIMIT; + } + /** + * Check if the size (length or count) of the specified limit property is + * over the limit + * + * @param limit the type of the limit property + * @param entityName the name of the entity + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(Limit limit, String entityName, int size) { + return isOverLimit(limit.ordinal(), entityName, size); + } + + /** + * Check if the value (length or count) of the specified limit property is + * over the limit + * + * @param index the index of the limit property + * @param entityName the name of the entity + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(int index, String entityName, int size) { + if (values[index] == NO_LIMIT) { + return false; + } + if (size > values[index]) { + limitAnalyzer.addValue(index, entityName, size); + return true; + } + return false; + } + + /** + * Check against cumulated value + * + * @param limit the type of the limit property + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(Limit limit) { + return isOverLimit(limit.ordinal()); + } + + public boolean isOverLimit(int index) { + if (values[index] == NO_LIMIT) { + return false; + } + + if (index==Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || + index==Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index==Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) { + return (limitAnalyzer.getTotalValue(index) > values[index]); + } else { + return (limitAnalyzer.getValue(index) > values[index]); + } + } + + public void debugPrint() { + if (printEntityCountInfo.equals(Constants.JDK_YES)) { + limitAnalyzer.debugPrint(); + } + } + + /** + * Return the limit analyzer + * + * @return the limit analyzer + */ + public XMLLimitAnalyzer getLimitAnalyzer() { + return limitAnalyzer; + } + + /** + * Set limit analyzer + * + * @param analyzer a limit analyzer + */ + public void setLimitAnalyzer(XMLLimitAnalyzer analyzer) { + limitAnalyzer = analyzer; + } + + /** + * Indicate if a property is set explicitly + * @param index + * @return + */ + public boolean isSet(int index) { + return isSet[index]; + } + + public boolean printEntityCountInfo() { + return printEntityCountInfo.equals(Constants.JDK_YES); } /** * Read from system properties, or those in jaxp.properties */ private void readSystemProperties() { - getSystemProperty(Limit.ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT); - getSystemProperty(Limit.MAX_OCCUR_NODE_LIMIT, Constants.MAX_OCCUR_LIMIT); - getSystemProperty(Limit.ELEMENT_ATTRIBUTE_LIMIT, - Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT); + + for (Limit limit : Limit.values()) { + if (!getSystemProperty(limit, limit.systemProperty())) { + //if system property is not found, try the older form if any + for (NameMap nameMap : NameMap.values()) { + String oldName = nameMap.getOldName(limit.systemProperty()); + if (oldName != null) { + getSystemProperty(limit, oldName); + } + } + } + } + } /** * Read from system properties, or those in jaxp.properties * - * @param limit the type of the property - * @param property the property name + * @param property the type of the property + * @param sysPropertyName the name of system property */ - private void getSystemProperty(Limit limit, String property) { + private boolean getSystemProperty(Limit limit, String sysPropertyName) { try { - String value = SecuritySupport.getSystemProperty(property); + String value = SecuritySupport.getSystemProperty(sysPropertyName); if (value != null && !value.equals("")) { - limits[limit.ordinal()] = Integer.parseInt(value); + values[limit.ordinal()] = Integer.parseInt(value); states[limit.ordinal()] = State.SYSTEMPROPERTY; - return; + return true; } - value = SecuritySupport.readJAXPProperty(property); + value = SecuritySupport.readJAXPProperty(sysPropertyName); if (value != null && !value.equals("")) { - limits[limit.ordinal()] = Integer.parseInt(value); + values[limit.ordinal()] = Integer.parseInt(value); states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + return true; } } catch (NumberFormatException e) { - //invalid setting ignored + //invalid setting + throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty()); } + return false; } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java index c6bb0310702..4286f043e50 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java @@ -91,6 +91,24 @@ public final class XMLSecurityPropertyManager { readSystemProperties(); } + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security property manager; + * false if otherwise. + */ + public boolean setValue(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setValue(index, state, (String)value); + return true; + } + return false; + } + /** * Set the value for a specific property. * @@ -119,6 +137,23 @@ public final class XMLSecurityPropertyManager { states[index] = state; } } + + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string + */ + public String getValue(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getValueByIndex(index); + } + + return null; + } + /** * Return the value of the specified property * diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index 805586093ca..a9c9aab1d50 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -25,6 +25,7 @@ package com.sun.org.apache.xml.internal.utils; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import java.util.HashMap; import javax.xml.XMLConstants; @@ -72,6 +73,8 @@ public class XMLReaderManager { */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityManager _xmlSecurityManager; + /** * Hidden constructor */ @@ -173,6 +176,21 @@ public class XMLReaderManager { + se.getMessage()); } + try { + if (_xmlSecurityManager != null) { + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + reader.setProperty(limit.apiProperty(), + _xmlSecurityManager.getLimitValueAsString(limit)); + } + if (_xmlSecurityManager.printEntityCountInfo()) { + reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES); + } + } + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } + return reader; } @@ -215,9 +233,11 @@ public class XMLReaderManager { /** * Get property value */ - public String getProperty(String name) { + public Object getProperty(String name) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { return _accessExternalDTD; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + return _xmlSecurityManager; } return null; } @@ -225,9 +245,11 @@ public class XMLReaderManager { /** * Set property. */ - public void setProperty(String name, String value) { + public void setProperty(String name, Object value) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { _accessExternalDTD = (String)value; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + _xmlSecurityManager = (XMLSecurityManager)value; } } } From d590d5e7d896a1b5ddda76668d698dafc40554dd Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 31 Jul 2013 10:54:46 -0700 Subject: [PATCH 010/152] 8021366: java_util/Properties/PropertiesWithOtherEncodings fails during 7u45 nightly testing Reviewed-by: lancea, alanb, dfuchs, mullan --- jaxp/src/com/sun/xml/internal/stream/Entity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jaxp/src/com/sun/xml/internal/stream/Entity.java b/jaxp/src/com/sun/xml/internal/stream/Entity.java index 7bbdf692412..0ae8228a3be 100644 --- a/jaxp/src/com/sun/xml/internal/stream/Entity.java +++ b/jaxp/src/com/sun/xml/internal/stream/Entity.java @@ -248,7 +248,7 @@ public abstract class Entity { public int fBufferSize = DEFAULT_BUFFER_SIZE; /** Default buffer size before we've finished with the XMLDecl: */ - public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64; + public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 28; /** Default internal entity buffer size (1024). */ public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024; From b520de4e1e7f245db43a627084be0ce7640c8c3b Mon Sep 17 00:00:00 2001 From: Miroslav Kos Date: Thu, 1 Aug 2013 16:09:17 -0400 Subject: [PATCH 011/152] 8017505: Better Client Service Reviewed-by: mullan, ahgross, mgrebac --- .../api/server/AbstractInstanceResolver.java | 4 +- .../ws/api/server/InstanceResolver.java | 4 +- .../internal/ws/api/server/MethodUtil.java | 94 +++++++++++++++++++ .../internal/ws/client/sei/MethodUtil.java | 94 +++++++++++++++++++ .../xml/internal/ws/client/sei/SEIStub.java | 23 ++++- .../ws/policy/privateutil/MethodUtil.java | 92 ++++++++++++++++++ .../ws/policy/privateutil/PolicyUtils.java | 8 +- 7 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java index e670ac452e6..560e98e9085 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. 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 @@ -66,7 +66,7 @@ public abstract class AbstractInstanceResolver extends InstanceResolver { if (!method.isAccessible()) { method.setAccessible(true); } - method.invoke(instance,args); + MethodUtil.invoke(instance,method, args); } catch (IllegalAccessException e) { throw new ServerRtException("server.rt.err",e); } catch (InvocationTargetException e) { diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java index 625f59f47b0..7c11e6455f7 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. 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 @@ -232,7 +232,7 @@ public abstract class InstanceResolver { public Object invoke(Packet p, Method m, Object... args) throws InvocationTargetException, IllegalAccessException { T t = resolve(p); try { - return m.invoke(t, args ); + return MethodUtil.invoke(t, m, args ); } finally { postInvoke(p,t); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java new file mode 100644 index 00000000000..c8497055678 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.api.server; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks + * to java.lang,reflect.Method.invoke() + * + * Be careful, copy of this class exists in several packages, iny modification must be done to other copies too! + */ +class MethodUtil { + + private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName()); + private static final Method INVOKE_METHOD; + + static { + Method method; + try { + Class clazz = Class.forName("sun.reflect.misc.MethodUtil"); + method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods."); + } + } catch (Throwable t) { + method = null; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM"); + } + } + INVOKE_METHOD = method; + } + + static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException { + if (INVOKE_METHOD != null) { + // sun.reflect.misc.MethodUtil.invoke(method, owner, args) + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil"); + } + try { + return INVOKE_METHOD.invoke(null, method, target, args); + } catch (InvocationTargetException ite) { + // unwrap invocation exception added by reflection code ... + throw unwrapException(ite); + } + } else { + // other then Oracle JDK ... + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM"); + } + return method.invoke(target, args); + } + } + + private static InvocationTargetException unwrapException(InvocationTargetException ite) { + Throwable targetException = ite.getTargetException(); + if (targetException != null && targetException instanceof InvocationTargetException) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Unwrapping invocation target exception"); + } + return (InvocationTargetException) targetException; + } else { + return ite; + } + } + +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java new file mode 100644 index 00000000000..f0daea51faf --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.client.sei; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks + * to java.lang,reflect.Method.invoke() + *

    + * Be careful, copy of this class exists in several packages, iny modification must be done to other copies too! + */ +class MethodUtil { + + private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName()); + private static final Method INVOKE_METHOD; + + static { + Method method; + try { + Class clazz = Class.forName("sun.reflect.misc.MethodUtil"); + method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods."); + } + } catch (Throwable t) { + method = null; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM"); + } + } + INVOKE_METHOD = method; + } + + static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException { + if (INVOKE_METHOD != null) { + // sun.reflect.misc.MethodUtil.invoke(method, owner, args) + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil"); + } + try { + return INVOKE_METHOD.invoke(null, method, target, args); + } catch (InvocationTargetException ite) { + // unwrap invocation exception added by reflection code ... + throw unwrapException(ite); + } + } else { + // other then Oracle JDK ... + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM"); + } + return method.invoke(target, args); + } + } + + private static InvocationTargetException unwrapException(InvocationTargetException ite) { + Throwable targetException = ite.getTargetException(); + if (targetException != null && targetException instanceof InvocationTargetException) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Unwrapping invocation target exception"); + } + return (InvocationTargetException) targetException; + } else { + return ite; + } + } + +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java index 7a5f0e3a1a7..9ad1f6edfba 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java @@ -28,6 +28,7 @@ package com.sun.xml.internal.ws.client.sei; import com.sun.istack.internal.NotNull; import com.sun.istack.internal.Nullable; import com.sun.xml.internal.ws.api.SOAPVersion; +import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; import com.sun.xml.internal.ws.api.client.WSPortInfo; import com.sun.xml.internal.ws.api.databinding.Databinding; import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; @@ -36,12 +37,16 @@ import com.sun.xml.internal.ws.api.message.Headers; import com.sun.xml.internal.ws.api.message.Packet; import com.sun.xml.internal.ws.api.model.MEP; import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation; -import com.sun.xml.internal.ws.api.pipe.Tube; import com.sun.xml.internal.ws.api.pipe.Fiber; +import com.sun.xml.internal.ws.api.pipe.Tube; import com.sun.xml.internal.ws.api.server.Container; import com.sun.xml.internal.ws.api.server.ContainerResolver; import com.sun.xml.internal.ws.binding.BindingImpl; -import com.sun.xml.internal.ws.client.*; +import com.sun.xml.internal.ws.client.AsyncResponseImpl; +import com.sun.xml.internal.ws.client.RequestContext; +import com.sun.xml.internal.ws.client.ResponseContextReceiver; +import com.sun.xml.internal.ws.client.Stub; +import com.sun.xml.internal.ws.client.WSServiceDelegate; import com.sun.xml.internal.ws.model.JavaMethodImpl; import com.sun.xml.internal.ws.model.SOAPSEIModel; import com.sun.xml.internal.ws.wsdl.OperationDispatcher; @@ -50,6 +55,8 @@ import javax.xml.namespace.QName; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; @@ -132,6 +139,7 @@ public final class SEIStub extends Stub implements InvocationHandler { private final Map methodHandlers = new HashMap(); public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + validateInputs(proxy, method); Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); try { MethodHandler handler = methodHandlers.get(method); @@ -155,6 +163,17 @@ public final class SEIStub extends Stub implements InvocationHandler { } } + private void validateInputs(Object proxy, Method method) { + if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) { + throw new IllegalStateException("Passed object is not proxy!"); + } + Class declaringClass = method.getDeclaringClass(); + if (method == null || declaringClass == null + || Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Invoking static method is not allowed!"); + } + } + public final Packet doProcess(Packet request, RequestContext rc, ResponseContextReceiver receiver) { return super.process(request, rc, receiver); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java new file mode 100644 index 00000000000..ad2ad4a6ef5 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.policy.privateutil; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks + * to java.lang,reflect.Method.invoke() + */ +class MethodUtil { + + private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName()); + private static final Method INVOKE_METHOD; + + static { + Method method; + try { + Class clazz = Class.forName("sun.reflect.misc.MethodUtil"); + method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods."); + } + } catch (Throwable t) { + method = null; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM"); + } + } + INVOKE_METHOD = method; + } + + static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException { + if (INVOKE_METHOD != null) { + // sun.reflect.misc.MethodUtil.invoke(method, owner, args) + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil"); + } + try { + return INVOKE_METHOD.invoke(null, method, target, args); + } catch (InvocationTargetException ite) { + // unwrap invocation exception added by reflection code ... + throw unwrapException(ite); + } + } else { + // other then Oracle JDK ... + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM"); + } + return method.invoke(target, args); + } + } + + private static InvocationTargetException unwrapException(InvocationTargetException ite) { + Throwable targetException = ite.getTargetException(); + if (targetException != null && targetException instanceof InvocationTargetException) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Unwrapping invocation target exception"); + } + return (InvocationTargetException) targetException; + } else { + return ite; + } + } + +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java index d3a2752ad5e..ec537d88358 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -282,13 +282,13 @@ public final class PolicyUtils { /** * Reflection utilities wrapper */ - public static class Reflection { + static class Reflection { private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtils.Reflection.class); /** * Reflectively invokes specified method on the specified target */ - public static T invoke(final Object target, final String methodName, + static T invoke(final Object target, final String methodName, final Class resultClass, final Object... parameters) throws RuntimePolicyUtilsException { Class[] parameterTypes; if (parameters != null && parameters.length > 0) { @@ -311,7 +311,7 @@ public final class PolicyUtils { final Object[] parameters, final Class[] parameterTypes) throws RuntimePolicyUtilsException { try { final Method method = target.getClass().getMethod(methodName, parameterTypes); - final Object result = method.invoke(target, parameters); + final Object result = MethodUtil.invoke(target, method,parameters); return resultClass.cast(result); } catch (IllegalArgumentException e) { From b2e34525abe6f046e30087a74b9c66200784a524 Mon Sep 17 00:00:00 2001 From: Sergey Gabdurakhmanov Date: Fri, 9 Aug 2013 11:03:33 +0400 Subject: [PATCH 012/152] 8020789: Disable exporting of gc.heap_dump diagnostic command Reviewed-by: fparain, ahgross --- hotspot/src/share/vm/services/diagnosticCommand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 79c922a8586..162010e425e 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -48,7 +48,7 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #if INCLUDE_SERVICES // Heap dumping/inspection supported - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #endif // INCLUDE_SERVICES From 49058214db19c8fa61461a60b97b77e3d2ab3fbe Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Mon, 19 Aug 2013 15:22:59 +0100 Subject: [PATCH 013/152] 8022940: Enhance CORBA translations Reviewed-by: coffeys, alanb, skoivu --- .../rmi/IDLNameTranslatorImpl.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java index dfe6581cc11..86a47992a72 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java @@ -905,28 +905,4 @@ public class IDLNameTranslatorImpl implements IDLNameTranslator { return contents.toString(); } - - public static void main(String[] args) { - - Class remoteInterface = java.rmi.Remote.class; - - if( args.length > 0 ) { - String className = args[0]; - try { - remoteInterface = Class.forName(className); - } catch(Exception e) { - e.printStackTrace(); - System.exit(-1); - } - } - - System.out.println("Building name translation for " + remoteInterface); - try { - IDLNameTranslator nameTranslator = - IDLNameTranslatorImpl.get(remoteInterface); - System.out.println(nameTranslator); - } catch(IllegalStateException ise) { - ise.printStackTrace(); - } - } } From 1b5eaa621e907e871ba0637cb7510ae7795f94de Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 19 Aug 2013 17:47:21 +0200 Subject: [PATCH 014/152] 8015614: Update build settings Reviewed-by: tbell, dholmes, ahgross --- hotspot/make/windows/makefiles/compile.make | 9 +++++++-- hotspot/make/windows/makefiles/sa.make | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make index 6f8dcce3406..93454d75399 100644 --- a/hotspot/make/windows/makefiles/compile.make +++ b/hotspot/make/windows/makefiles/compile.make @@ -180,6 +180,7 @@ DEBUG_OPT_OPTION = /Od PRODUCT_OPT_OPTION = /O2 /Oy- FASTDEBUG_OPT_OPTION = /O2 /Oy- DEBUG_OPT_OPTION = /Od +SAFESEH_FLAG = /SAFESEH !endif !if "$(COMPILER_NAME)" == "VS2005" @@ -198,6 +199,7 @@ LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB) !if "x$(MT)" == "x" MT=mt.exe !endif +SAFESEH_FLAG = /SAFESEH !endif !if "$(COMPILER_NAME)" == "VS2008" @@ -211,6 +213,7 @@ LD_FLAGS = /manifest $(LD_FLAGS) !if "x$(MT)" == "x" MT=mt.exe !endif +SAFESEH_FLAG = /SAFESEH !endif !if "$(COMPILER_NAME)" == "VS2010" @@ -240,9 +243,11 @@ LD_FLAGS = /manifest $(LD_FLAGS) !if "x$(MT)" == "x" MT=mt.exe !endif -!if "$(BUILDARCH)" == "i486" -LD_FLAGS = /SAFESEH $(LD_FLAGS) +SAFESEH_FLAG = /SAFESEH !endif + +!if "$(BUILDARCH)" == "i486" +LD_FLAGS = $(SAFESEH_FLAG) $(LD_FLAGS) !endif # If NO_OPTIMIZATIONS is defined in the environment, turn everything off diff --git a/hotspot/make/windows/makefiles/sa.make b/hotspot/make/windows/makefiles/sa.make index 9363f0e5e6f..356c4fd6b50 100644 --- a/hotspot/make/windows/makefiles/sa.make +++ b/hotspot/make/windows/makefiles/sa.make @@ -107,6 +107,9 @@ SA_LFLAGS = $(SA_LD_FLAGS) -nologo -subsystem:console -machine:$(MACHINE) !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" SA_LFLAGS = $(SA_LFLAGS) -map -debug !endif +!if "$(BUILDARCH)" == "i486" +SA_LFLAGS = $(SAFESEH_FLAG) $(SA_LFLAGS) +!endif # Note that we do not keep sawindbj.obj around as it would then # get included in the dumpbin command in build_vm_def.sh From b3505de64053a05578292514fec3477980b90e8a Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 20 Aug 2013 09:02:25 -0700 Subject: [PATCH 015/152] 8022682: Supporting XOM Reviewed-by: alanb, chegar, lancea --- .../xerces/internal/impl/PropertyManager.java | 19 ++ .../jaxp/validation/XMLSchemaFactory.java | 10 +- .../xerces/internal/parsers/DOMParser.java | 48 ++++ .../internal/parsers/DTDConfiguration.java | 11 +- .../parsers/NonValidatingConfiguration.java | 11 +- .../xerces/internal/parsers/SAXParser.java | 40 +++- .../internal/parsers/XML11Configuration.java | 4 - .../xerces/internal/parsers/XMLParser.java | 18 ++ .../xerces/internal/util/SecurityManager.java | 215 ++++++++++++++++++ .../internal/utils/XMLLimitAnalyzer.java | 3 + .../internal/utils/XMLSecurityManager.java | 34 +++ 11 files changed, 395 insertions(+), 18 deletions(-) create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index 8fbf9162409..2c8f3aff2c2 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -178,6 +178,25 @@ public class PropertyManager { supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; } + /** + * It's possible for users to set a security manager through the interface. + * If it's the old SecurityManager, convert it to the new XMLSecurityManager + */ + if (property.equals(Constants.SECURITY_MANAGER)) { + fSecurityManager = XMLSecurityManager.convert(value, fSecurityManager); + supportedProps.put(Constants.SECURITY_MANAGER, fSecurityManager); + return; + } + if (property.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (value == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + } else { + fSecurityPropertyMgr = (XMLSecurityPropertyManager)value; + } + supportedProps.put(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + return; + } + //check if the property is managed by security manager if (fSecurityManager == null || !fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 34eba4c4791..f2dadd0fc4a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -408,9 +408,17 @@ public final class XMLSchemaFactory extends SchemaFactory { "ProperyNameNull", null)); } if (name.equals(SECURITY_MANAGER)) { - fSecurityManager = (XMLSecurityManager) object; + fSecurityManager = XMLSecurityManager.convert(object, fSecurityManager); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); return; + } else if (name.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (object == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + } else { + fSecurityPropertyMgr = (XMLSecurityPropertyManager)object; + } + fXMLSchemaLoader.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + return; } else if (name.equals(XMLGRAMMAR_POOL)) { throw new SAXNotSupportedException( diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java index f681fadbd33..f2020efda4b 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java @@ -29,6 +29,7 @@ import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; @@ -531,7 +532,54 @@ public class DOMParser */ public void setProperty(String propertyId, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { + /** + * It's possible for users to set a security manager through the interface. + * If it's the old SecurityManager, convert it to the new XMLSecurityManager + */ + if (propertyId.equals(Constants.SECURITY_MANAGER)) { + securityManager = XMLSecurityManager.convert(value, securityManager); + setProperty0(Constants.SECURITY_MANAGER, securityManager); + return; + } + if (propertyId.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (value == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } else { + securityPropertyManager = (XMLSecurityPropertyManager)value; + } + setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + return; + } + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + setProperty0(Constants.SECURITY_MANAGER, securityManager); + } + + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + } + int index = securityPropertyManager.getIndex(propertyId); + + if (index > -1) { + /** + * this is a direct call to this parser, not a subclass since + * internally the support of this property is done through + * XMLSecurityPropertyManager + */ + securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + } else { + //check if the property is managed by security manager + if (!securityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) { + //fall back to the default configuration to handle the property + setProperty0(propertyId, value); + } + } + } + + public void setProperty0(String propertyId, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException { try { fConfiguration.setProperty(propertyId, value); } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java index 0cdfd654b78..838dd9f5ec4 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java @@ -184,6 +184,13 @@ public class DTDConfiguration protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Property identifier: Security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -328,7 +335,9 @@ public class DTDConfiguration VALIDATION_MANAGER, JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, - LOCALE + LOCALE, + SECURITY_MANAGER, + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java index 55339157c90..fb81834fce9 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java @@ -157,6 +157,13 @@ public class NonValidatingConfiguration protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Property identifier: Security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -310,7 +317,9 @@ public class NonValidatingConfiguration XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER, - LOCALE + LOCALE, + SECURITY_MANAGER, + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java index 8432b54541e..48b8a1ed538 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java @@ -77,8 +77,7 @@ public class SAXParser XMLGRAMMAR_POOL, }; - XMLSecurityManager securityManager; - XMLSecurityPropertyManager securityPropertyManager; + // // Constructors // @@ -132,9 +131,35 @@ public class SAXParser */ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { + /** + * It's possible for users to set a security manager through the interface. + * If it's the old SecurityManager, convert it to the new XMLSecurityManager + */ + if (name.equals(Constants.SECURITY_MANAGER)) { + securityManager = XMLSecurityManager.convert(value, securityManager); + super.setProperty(Constants.SECURITY_MANAGER, securityManager); + return; + } + if (name.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (value == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } else { + securityPropertyManager = (XMLSecurityPropertyManager)value; + } + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + return; + } + + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + super.setProperty(Constants.SECURITY_MANAGER, securityManager); + } + if (securityPropertyManager == null) { securityPropertyManager = new XMLSecurityPropertyManager(); + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); } + int index = securityPropertyManager.getIndex(name); if (index > -1) { /** @@ -143,19 +168,12 @@ public class SAXParser * XMLSecurityPropertyManager */ securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); } else { - if (securityManager == null) { - securityManager = new XMLSecurityManager(true); - } - //check if the property is managed by security manager - if (securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { - super.setProperty(Constants.SECURITY_MANAGER, securityManager); - } else { + if (!securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + //fall back to the default configuration to handle the property super.setProperty(name, value); } - } } } // class SAXParser diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 3f22807e37e..bbcbceed10e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -583,10 +583,6 @@ public class XML11Configuration extends ParserConfigurationSettings fVersionDetector = new XMLVersionDetector(); - fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); - - fProperties.put(SECURITY_MANAGER, new XMLSecurityManager(true)); - // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { XMLMessageFormatter xmft = new XMLMessageFormatter(); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java index 210b7ce9cc6..970cc51cd26 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java @@ -23,6 +23,8 @@ package com.sun.org.apache.xerces.internal.parsers; import java.io.IOException; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; @@ -78,6 +80,13 @@ public abstract class XMLParser { /** The parser configuration. */ protected XMLParserConfiguration fConfiguration; + /** The XML Security Manager. */ + XMLSecurityManager securityManager; + + /** The XML Security Property Manager. */ + XMLSecurityPropertyManager securityPropertyManager; + + // // Constructors // @@ -118,6 +127,15 @@ public abstract class XMLParser { */ public void parse(XMLInputSource inputSource) throws XNIException, IOException { + // null indicates that the parser is called directly, initialize them + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + fConfiguration.setProperty(Constants.SECURITY_MANAGER, securityManager); + } + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + fConfiguration.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + } reset(); fConfiguration.parse(inputSource); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java new file mode 100644 index 00000000000..d916f5bc516 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java @@ -0,0 +1,215 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * The Apache Software License, Version 1.1 + * + * + * Copyright (c) 2003 The Apache Software Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.apache.org. For more + * information on the Apache Software Foundation, please see + * . + */ + +package com.sun.org.apache.xerces.internal.util; +import com.sun.org.apache.xerces.internal.impl.Constants; +/** + * This class is a container for parser settings that relate to + * security, or more specifically, it is intended to be used to prevent denial-of-service + * attacks from being launched against a system running Xerces. + * Any component that is aware of a denial-of-service attack that can arise + * from its processing of a certain kind of document may query its Component Manager + * for the property (http://apache.org/xml/properties/security-manager) + * whose value will be an instance of this class. + * If no value has been set for the property, the component should proceed in the "usual" (spec-compliant) + * manner. If a value has been set, then it must be the case that the component in + * question needs to know what method of this class to query. This class + * will provide defaults for all known security issues, but will also provide + * setters so that those values can be tailored by applications that care. + * + * @author Neil Graham, IBM + * + */ +public final class SecurityManager { + + // + // Constants + // + + // default value for entity expansion limit + private final static int DEFAULT_ENTITY_EXPANSION_LIMIT = 64000; + + /** Default value of number of nodes created. **/ + private final static int DEFAULT_MAX_OCCUR_NODE_LIMIT = 5000; + + // + // Data + // + + private final static int DEFAULT_ELEMENT_ATTRIBUTE_LIMIT = 10000; + + /** Entity expansion limit. **/ + private int entityExpansionLimit; + + /** W3C XML Schema maxOccurs limit. **/ + private int maxOccurLimit; + + private int fElementAttributeLimit; + // default constructor. Establishes default values for + // all known security holes. + /** + * Default constructor. Establishes default values + * for known security vulnerabilities. + */ + public SecurityManager() { + entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; + maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT ; + fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; + //We are reading system properties only once , + //at the time of creation of this object , + readSystemProperties(); + } + + /** + *

    Sets the number of entity expansions that the + * parser should permit in a document.

    + * + * @param limit the number of entity expansions + * permitted in a document + */ + public void setEntityExpansionLimit(int limit) { + entityExpansionLimit = limit; + } + + /** + *

    Returns the number of entity expansions + * that the parser permits in a document.

    + * + * @return the number of entity expansions + * permitted in a document + */ + public int getEntityExpansionLimit() { + return entityExpansionLimit; + } + + /** + *

    Sets the limit of the number of content model nodes + * that may be created when building a grammar for a W3C + * XML Schema that contains maxOccurs attributes with values + * other than "unbounded".

    + * + * @param limit the maximum value for maxOccurs other + * than "unbounded" + */ + public void setMaxOccurNodeLimit(int limit){ + maxOccurLimit = limit; + } + + /** + *

    Returns the limit of the number of content model nodes + * that may be created when building a grammar for a W3C + * XML Schema that contains maxOccurs attributes with values + * other than "unbounded".

    + * + * @return the maximum value for maxOccurs other + * than "unbounded" + */ + public int getMaxOccurNodeLimit(){ + return maxOccurLimit; + } + + public int getElementAttrLimit(){ + return fElementAttributeLimit; + } + + public void setElementAttrLimit(int limit){ + fElementAttributeLimit = limit; + } + + private void readSystemProperties(){ + + try { + String value = System.getProperty(Constants.ENTITY_EXPANSION_LIMIT); + if(value != null && !value.equals("")){ + entityExpansionLimit = Integer.parseInt(value); + if (entityExpansionLimit < 0) + entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; + } + else + entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; + }catch(Exception ex){} + + try { + String value = System.getProperty(Constants.MAX_OCCUR_LIMIT); + if(value != null && !value.equals("")){ + maxOccurLimit = Integer.parseInt(value); + if (maxOccurLimit < 0) + maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; + } + else + maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; + }catch(Exception ex){} + + try { + String value = System.getProperty(Constants.ELEMENT_ATTRIBUTE_LIMIT); + if(value != null && !value.equals("")){ + fElementAttributeLimit = Integer.parseInt(value); + if ( fElementAttributeLimit < 0) + fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; + } + else + fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; + + }catch(Exception ex){} + + } + +} // class SecurityManager diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java index 41724b6c50d..82667edeed0 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java @@ -203,6 +203,9 @@ public final class XMLLimitAnalyzer { } public boolean isTracking(String name) { + if (entityStart == null) { + return false; + } return entityStart.equals(name); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java index 1ddb651d6df..a28e80dc81a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java @@ -26,6 +26,7 @@ package com.sun.org.apache.xerces.internal.utils; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.util.SecurityManager; /** * This class manages standard and implementation-specific limitations. @@ -518,4 +519,37 @@ public final class XMLSecurityManager { } return false; } + + + /** + * Convert a value set through setProperty to XMLSecurityManager. + * If the value is an instance of XMLSecurityManager, use it to override the default; + * If the value is an old SecurityManager, convert to the new XMLSecurityManager. + * + * @param value user specified security manager + * @param securityManager an instance of XMLSecurityManager + * @return an instance of the new security manager XMLSecurityManager + */ + static public XMLSecurityManager convert(Object value, XMLSecurityManager securityManager) { + if (value == null) { + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + return securityManager; + } + if (XMLSecurityManager.class.isAssignableFrom(value.getClass())) { + return (XMLSecurityManager)value; + } else { + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + if (SecurityManager.class.isAssignableFrom(value.getClass())) { + SecurityManager origSM = (SecurityManager)value; + securityManager.setLimit(Limit.MAX_OCCUR_NODE_LIMIT, State.APIPROPERTY, origSM.getMaxOccurNodeLimit()); + securityManager.setLimit(Limit.ENTITY_EXPANSION_LIMIT, State.APIPROPERTY, origSM.getEntityExpansionLimit()); + securityManager.setLimit(Limit.ELEMENT_ATTRIBUTE_LIMIT, State.APIPROPERTY, origSM.getElementAttrLimit()); + } + return securityManager; + } + } } From e412d7e8d119d5d23af15efecac7945f528a993f Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Sat, 24 Aug 2013 00:14:46 -0700 Subject: [PATCH 016/152] 8023683: Enhance class file parsing Use the value returned by REALLOC_RESOURCE_ARRAY() Reviewed-by: coleenp, ahgross --- hotspot/src/share/vm/classfile/classFileParser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index e7b9c90363b..9ef6af65475 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2178,8 +2178,8 @@ methodHandle ClassFileParser::parse_method(bool is_interface, } if (lvt_cnt == max_lvt_cnt) { max_lvt_cnt <<= 1; - REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); - REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); + localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); + localvariable_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); } localvariable_table_start[lvt_cnt] = parse_localvariable_table(code_length, @@ -2207,8 +2207,8 @@ methodHandle ClassFileParser::parse_method(bool is_interface, // Parse local variable type table if (lvtt_cnt == max_lvtt_cnt) { max_lvtt_cnt <<= 1; - REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); - REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); + localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); + localvariable_type_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); } localvariable_type_table_start[lvtt_cnt] = parse_localvariable_table(code_length, From 619948a8f1ff9deca30032edf9c523d84396ca93 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Mon, 7 Oct 2013 10:41:56 -0700 Subject: [PATCH 017/152] 8025566: EXCEPTION_ACCESS_VIOLATION in compiled by C1 String.valueOf method Reviewed-by: kvn --- hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 6 +++++- hotspot/src/share/vm/ci/ciMethod.cpp | 17 +++++++++-------- hotspot/src/share/vm/ci/ciMethod.hpp | 2 +- hotspot/src/share/vm/ci/ciMethodData.cpp | 4 +++- hotspot/src/share/vm/ci/ciMethodData.hpp | 2 -- hotspot/src/share/vm/ci/ciReplay.cpp | 6 ++---- hotspot/src/share/vm/oops/method.hpp | 2 +- hotspot/src/share/vm/opto/parseHelper.cpp | 8 ++++++-- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index dbe3476aad9..f71470e5ee0 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -3053,7 +3053,11 @@ void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info, int offset = -1; LIR_Opr counter_holder; if (level == CompLevel_limited_profile) { - address counters_adr = method->ensure_method_counters(); + MethodCounters* counters_adr = method->ensure_method_counters(); + if (counters_adr == NULL) { + bailout("method counters allocation failed"); + return; + } counter_holder = new_pointer_register(); __ move(LIR_OprFact::intptrConst(counters_adr), counter_holder); offset = in_bytes(backedge ? MethodCounters::backedge_counter_offset() : diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index 15bb285a869..a5549702582 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -846,7 +846,9 @@ bool ciMethod::has_member_arg() const { // Return true if allocation was successful or no MDO is required. bool ciMethod::ensure_method_data(methodHandle h_m) { EXCEPTION_CONTEXT; - if (is_native() || is_abstract() || h_m()->is_accessor()) return true; + if (is_native() || is_abstract() || h_m()->is_accessor()) { + return true; + } if (h_m()->method_data() == NULL) { Method::build_interpreter_method_data(h_m, THREAD); if (HAS_PENDING_EXCEPTION) { @@ -903,22 +905,21 @@ ciMethodData* ciMethod::method_data() { // NULL otherwise. ciMethodData* ciMethod::method_data_or_null() { ciMethodData *md = method_data(); - if (md->is_empty()) return NULL; + if (md->is_empty()) { + return NULL; + } return md; } // ------------------------------------------------------------------ // ciMethod::ensure_method_counters // -address ciMethod::ensure_method_counters() { +MethodCounters* ciMethod::ensure_method_counters() { check_is_loaded(); VM_ENTRY_MARK; methodHandle mh(THREAD, get_Method()); - MethodCounters *counter = mh->method_counters(); - if (counter == NULL) { - counter = Method::build_method_counters(mh(), CHECK_AND_CLEAR_NULL); - } - return (address)counter; + MethodCounters* method_counters = mh->get_method_counters(CHECK_NULL); + return method_counters; } // ------------------------------------------------------------------ diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index ddff0ac9b9a..ecbbfefd4d6 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -265,7 +265,7 @@ class ciMethod : public ciMetadata { bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const; bool check_call(int refinfo_index, bool is_static) const; bool ensure_method_data(); // make sure it exists in the VM also - address ensure_method_counters(); + MethodCounters* ensure_method_counters(); int instructions_size(); int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index 515401bc17b..268888bfd56 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -78,7 +78,9 @@ ciMethodData::ciMethodData() : ciMetadata(NULL) { void ciMethodData::load_data() { MethodData* mdo = get_MethodData(); - if (mdo == NULL) return; + if (mdo == NULL) { + return; + } // To do: don't copy the data if it is not "ripe" -- require a minimum # // of invocations. diff --git a/hotspot/src/share/vm/ci/ciMethodData.hpp b/hotspot/src/share/vm/ci/ciMethodData.hpp index ea650cbd721..913ae31847e 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.hpp +++ b/hotspot/src/share/vm/ci/ciMethodData.hpp @@ -232,8 +232,6 @@ private: public: bool is_method_data() const { return true; } - void set_mature() { _state = mature_state; } - bool is_empty() { return _state == empty_state; } bool is_mature() { return _state == mature_state; } diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp index 837d529ca13..3c8ccf9bb87 100644 --- a/hotspot/src/share/vm/ci/ciReplay.cpp +++ b/hotspot/src/share/vm/ci/ciReplay.cpp @@ -965,14 +965,12 @@ void ciReplay::initialize(ciMethod* m) { tty->cr(); } else { EXCEPTION_CONTEXT; - MethodCounters* mcs = method->method_counters(); // m->_instructions_size = rec->instructions_size; m->_instructions_size = -1; m->_interpreter_invocation_count = rec->interpreter_invocation_count; m->_interpreter_throwout_count = rec->interpreter_throwout_count; - if (mcs == NULL) { - mcs = Method::build_method_counters(method, CHECK_AND_CLEAR); - } + MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR); + guarantee(mcs != NULL, "method counters allocation failed"); mcs->invocation_counter()->_counter = rec->invocation_counter; mcs->backedge_counter()->_counter = rec->backedge_counter; } diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 02d2253b80a..41aafab9aef 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -804,6 +804,7 @@ class Method : public Metadata { private: void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); + public: MethodCounters* get_method_counters(TRAPS) { if (_method_counters == NULL) { build_method_counters(this, CHECK_AND_CLEAR_NULL); @@ -811,7 +812,6 @@ class Method : public Metadata { return _method_counters; } - public: bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); } diff --git a/hotspot/src/share/vm/opto/parseHelper.cpp b/hotspot/src/share/vm/opto/parseHelper.cpp index 5d0c2f7befe..2ab580b5ce5 100644 --- a/hotspot/src/share/vm/opto/parseHelper.cpp +++ b/hotspot/src/share/vm/opto/parseHelper.cpp @@ -343,10 +343,14 @@ void Parse::increment_and_test_invocation_counter(int limit) { // Get the Method* node. ciMethod* m = method(); - address counters_adr = m->ensure_method_counters(); + MethodCounters* counters_adr = m->ensure_method_counters(); + if (counters_adr == NULL) { + C->record_failure("method counters allocation failed"); + return; + } Node* ctrl = control(); - const TypePtr* adr_type = TypeRawPtr::make(counters_adr); + const TypePtr* adr_type = TypeRawPtr::make((address) counters_adr); Node *counters_node = makecon(adr_type); Node* adr_iic_node = basic_plus_adr(counters_node, counters_node, MethodCounters::interpreter_invocation_counter_offset_in_bytes()); From 59adc04ee5a012d41d95060fd7df89d2fa8c8c90 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Thu, 3 Oct 2013 10:55:07 +0200 Subject: [PATCH 018/152] 8024067: Missing replace_in_map() calls following null checks Add replace_in_map() calls following some null checks in type checks Reviewed-by: kvn --- hotspot/src/share/vm/opto/graphKit.cpp | 13 ++++++++++--- hotspot/src/share/vm/opto/graphKit.hpp | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 684ccc67aa1..93190011f78 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -2122,7 +2122,7 @@ Node* GraphKit::dstore_rounding(Node* n) { // Null check oop. Set null-path control into Region in slot 3. // Make a cast-not-nullness use the other not-null control. Return cast. Node* GraphKit::null_check_oop(Node* value, Node* *null_control, - bool never_see_null) { + bool never_see_null, bool safe_for_replace) { // Initial NULL check taken path (*null_control) = top(); Node* cast = null_check_common(value, T_OBJECT, false, null_control); @@ -2140,6 +2140,9 @@ Node* GraphKit::null_check_oop(Node* value, Node* *null_control, Deoptimization::Action_make_not_entrant); (*null_control) = top(); // NULL path is dead } + if ((*null_control) == top() && safe_for_replace) { + replace_in_map(value, cast); + } // Cast away null-ness on the result return cast; @@ -2634,15 +2637,17 @@ Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) { C->set_has_split_ifs(true); // Has chance for split-if optimization ciProfileData* data = NULL; + bool safe_for_replace = false; if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode data = method()->method_data()->bci_to_data(bci()); + safe_for_replace = true; } bool never_see_null = (ProfileDynamicTypes // aggressive use of profile && seems_never_null(obj, data)); // Null check; get casted pointer; set region slot 3 Node* null_ctl = top(); - Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null); + Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace); // If not_null_obj is dead, only null-path is taken if (stopped()) { // Doing instance-of on a NULL? @@ -2723,11 +2728,13 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, } ciProfileData* data = NULL; + bool safe_for_replace = false; if (failure_control == NULL) { // use MDO in regular case only assert(java_bc() == Bytecodes::_aastore || java_bc() == Bytecodes::_checkcast, "interpreter profiles type checks only for these BCs"); data = method()->method_data()->bci_to_data(bci()); + safe_for_replace = true; } // Make the merge point @@ -2742,7 +2749,7 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, // Null check; get casted pointer; set region slot 3 Node* null_ctl = top(); - Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null); + Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace); // If not_null_obj is dead, only null-path is taken if (stopped()) { // Doing instance-of on a NULL? diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp index 1fd4e86d2e7..f9c068d7c40 100644 --- a/hotspot/src/share/vm/opto/graphKit.hpp +++ b/hotspot/src/share/vm/opto/graphKit.hpp @@ -378,8 +378,10 @@ class GraphKit : public Phase { // Return a cast-not-null node which depends on the not-null control. // If never_see_null, use an uncommon trap (*null_control sees a top). // The cast is not valid along the null path; keep a copy of the original. + // If safe_for_replace, then we can replace the value with the cast + // in the parsing map (the cast is guaranteed to dominate the map) Node* null_check_oop(Node* value, Node* *null_control, - bool never_see_null = false); + bool never_see_null = false, bool safe_for_replace = false); // Check the null_seen bit. bool seems_never_null(Node* obj, ciProfileData* data); From 4f459e644f9b4733d372707e5c7b6e851eaf4c31 Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Fri, 4 Oct 2013 09:19:13 +0200 Subject: [PATCH 019/152] 8025656: compiler/8013496/Test8013496.sh fails on assert Ensure the thread is in correct state; rewrote test in Java Reviewed-by: kvn, twisti --- .../src/share/vm/compiler/compileBroker.cpp | 4 ++ hotspot/test/compiler/8013496/Test8013496.sh | 55 ------------------- ...kReservedInitialCodeCacheSizeArgOrder.java | 53 ++++++++++++++++++ 3 files changed, 57 insertions(+), 55 deletions(-) delete mode 100644 hotspot/test/compiler/8013496/Test8013496.sh create mode 100644 hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 594c58b5d68..8040224f77e 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -1953,6 +1953,10 @@ void CompileBroker::handle_full_code_cache() { // Since code cache is full, immediately stop new compiles if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) { NMethodSweeper::log_sweep("disable_compiler"); + + // Switch to 'vm_state'. This ensures that possibly_sweep() can be called + // without having to consider the state in which the current thread is. + ThreadInVMfromUnknown in_vm; NMethodSweeper::possibly_sweep(); } } else { diff --git a/hotspot/test/compiler/8013496/Test8013496.sh b/hotspot/test/compiler/8013496/Test8013496.sh deleted file mode 100644 index ae1d1fe34ff..00000000000 --- a/hotspot/test/compiler/8013496/Test8013496.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -# -# @test -# @bug 8013496 -# @summary Test checks that the order in which ReversedCodeCacheSize and -# InitialCodeCacheSize are passed to the VM is irrelevant. -# @run shell Test8013496.sh -# -# -## some tests require path to find test source dir -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh -set -x - -${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:ReservedCodeCacheSize=2m -XX:InitialCodeCacheSize=500K -version > 1.out 2>&1 -${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:InitialCodeCacheSize=500K -XX:ReservedCodeCacheSize=2m -version > 2.out 2>&1 - -diff 1.out 2.out - -result=$? -if [ $result -eq 0 ] ; then - echo "Test Passed" - exit 0 -else - echo "Test Failed" - exit 1 -fi diff --git a/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java b/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java new file mode 100644 index 00000000000..eea5c90e9f7 --- /dev/null +++ b/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8013496 + * @summary Test checks that the order in which ReversedCodeCacheSize and + * InitialCodeCacheSize are passed to the VM is irrelevant. + * @library /testlibrary + * + */ +import com.oracle.java.testlibrary.*; + +public class CheckReservedInitialCodeCacheSizeArgOrder { + public static void main(String[] args) throws Exception { + ProcessBuilder pb1, pb2; + OutputAnalyzer out1, out2; + + pb1 = ProcessTools.createJavaProcessBuilder("-XX:InitialCodeCacheSize=4m", "-XX:ReservedCodeCacheSize=8m", "-version"); + pb2 = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=8m", "-XX:InitialCodeCacheSize=4m", "-version"); + + out1 = new OutputAnalyzer(pb1.start()); + out2 = new OutputAnalyzer(pb2.start()); + + // Check that the outputs are equal + if (out1.getStdout().compareTo(out2.getStdout()) != 0) { + throw new RuntimeException("Test failed"); + } + + out1.shouldHaveExitValue(0); + out2.shouldHaveExitValue(0); + } +} From bfc53b6607c625bb44d103817924aed17c2441ac Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Fri, 4 Oct 2013 10:11:48 -0700 Subject: [PATCH 020/152] 8011138: C2: stack overflow in compiler thread because of recursive inlining of lambda form methods Reviewed-by: kvn, roland --- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 46 ++++++++++++++-------- hotspot/src/share/vm/opto/parse.hpp | 2 + 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 2ba7b1cf3b4..885ed1de643 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -197,6 +197,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, // negative filter: should callee NOT be inlined? bool InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, + JVMState* jvms, WarmCallInfo* wci_result) { const char* fail_msg = NULL; @@ -226,7 +227,7 @@ bool InlineTree::should_not_inline(ciMethod *callee_method, // don't inline exception code unless the top method belongs to an // exception class if (callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { - ciMethod* top_method = caller_jvms() ? caller_jvms()->of_depth(1)->method() : method(); + ciMethod* top_method = jvms->caller() != NULL ? jvms->caller()->of_depth(1)->method() : method(); if (!top_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { wci_result->set_profit(wci_result->profit() * 0.1); } @@ -328,7 +329,7 @@ bool InlineTree::should_not_inline(ciMethod *callee_method, // return true if ok // Relocated from "InliningClosure::try_to_inline" bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, - int caller_bci, ciCallProfile& profile, + int caller_bci, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) { // Old algorithm had funny accumulating BC-size counters @@ -346,7 +347,7 @@ bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, wci_result)) { return false; } - if (should_not_inline(callee_method, caller_method, wci_result)) { + if (should_not_inline(callee_method, caller_method, jvms, wci_result)) { return false; } @@ -397,24 +398,35 @@ bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, } // detect direct and indirect recursive inlining - if (!callee_method->is_compiled_lambda_form()) { + { // count the current method and the callee - int inline_level = (method() == callee_method) ? 1 : 0; - if (inline_level > MaxRecursiveInlineLevel) { - set_msg("recursively inlining too deep"); - return false; + const bool is_compiled_lambda_form = callee_method->is_compiled_lambda_form(); + int inline_level = 0; + if (!is_compiled_lambda_form) { + if (method() == callee_method) { + inline_level++; + } } // count callers of current method and callee - JVMState* jvms = caller_jvms(); - while (jvms != NULL && jvms->has_method()) { - if (jvms->method() == callee_method) { - inline_level++; - if (inline_level > MaxRecursiveInlineLevel) { - set_msg("recursively inlining too deep"); - return false; + Node* callee_argument0 = is_compiled_lambda_form ? jvms->map()->argument(jvms, 0)->uncast() : NULL; + for (JVMState* j = jvms->caller(); j != NULL && j->has_method(); j = j->caller()) { + if (j->method() == callee_method) { + if (is_compiled_lambda_form) { + // Since compiled lambda forms are heavily reused we allow recursive inlining. If it is truly + // a recursion (using the same "receiver") we limit inlining otherwise we can easily blow the + // compiler stack. + Node* caller_argument0 = j->map()->argument(j, 0)->uncast(); + if (caller_argument0 == callee_argument0) { + inline_level++; + } + } else { + inline_level++; } } - jvms = jvms->caller(); + } + if (inline_level > MaxRecursiveInlineLevel) { + set_msg("recursive inlining is too deep"); + return false; } } @@ -536,7 +548,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); bool success = try_to_inline(callee_method, caller_method, caller_bci, - profile, &wci, should_delay); + jvms, profile, &wci, should_delay); #ifndef PRODUCT if (UseOldInlining && InlineWarmCalls diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index ea01b08475e..f88ecf12dad 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -73,6 +73,7 @@ protected: bool try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, + JVMState* jvms, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay); @@ -83,6 +84,7 @@ protected: WarmCallInfo* wci_result); bool should_not_inline(ciMethod* callee_method, ciMethod* caller_method, + JVMState* jvms, WarmCallInfo* wci_result); void print_inlining(ciMethod* callee_method, int caller_bci, bool success) const; From 9cb5f396ae6bb72588bc3e032bebd38d1147ce95 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 7 Oct 2013 14:10:29 +0400 Subject: [PATCH 021/152] 8025849: Redundant "pid" in VM log file name (e.g. hotspot_pidpid12345.log) Reviewed-by: twisti, azeemj --- hotspot/src/share/vm/utilities/ostream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index e4215504a4d..39f87a47758 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -465,7 +465,7 @@ static const char* make_log_name_internal(const char* log_name, const char* forc } // log_name comes from -XX:LogFile=log_name or -Xloggc:log_name -// in log_name, %p => pipd1234 and +// in log_name, %p => pid1234 and // %t => YYYY-MM-DD_HH-MM-SS static const char* make_log_name(const char* log_name, const char* force_directory) { char timestr[32]; @@ -792,7 +792,7 @@ bool defaultStream::has_log_file() { void defaultStream::init_log() { // %%% Need a MutexLocker? - const char* log_name = LogFile != NULL ? LogFile : "hotspot_pid%p.log"; + const char* log_name = LogFile != NULL ? LogFile : "hotspot_%p.log"; const char* try_name = make_log_name(log_name, NULL); fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); if (!file->is_open()) { From 9edb09d8fbd314f2e8666738a07e57d4c1c31f16 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 7 Oct 2013 14:11:49 +0400 Subject: [PATCH 022/152] 8024943: ciReplay: fails to dump replay data during safepointing Reviewed-by: kvn, twisti --- hotspot/src/share/vm/ci/ciEnv.cpp | 16 +++++++++++++--- hotspot/src/share/vm/ci/ciEnv.hpp | 1 + hotspot/src/share/vm/ci/ciInstanceKlass.cpp | 1 - hotspot/src/share/vm/ci/ciMethod.cpp | 1 - hotspot/src/share/vm/ci/ciMethodData.cpp | 1 - hotspot/src/share/vm/utilities/vmError.cpp | 2 +- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index 0102b2b21f0..9cdd475a352 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -1154,9 +1154,12 @@ ciInstance* ciEnv::unloaded_ciinstance() { GUARDED_VM_ENTRY(return _factory->get_unloaded_object_constant();) } -void ciEnv::dump_replay_data(outputStream* out) { - VM_ENTRY_MARK; - MutexLocker ml(Compile_lock); +// ------------------------------------------------------------------ +// ciEnv::dump_replay_data* + +// Don't change thread state and acquire any locks. +// Safe to call from VM error reporter. +void ciEnv::dump_replay_data_unsafe(outputStream* out) { ResourceMark rm; #if INCLUDE_JVMTI out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables); @@ -1181,3 +1184,10 @@ void ciEnv::dump_replay_data(outputStream* out) { entry_bci, comp_level); out->flush(); } + +void ciEnv::dump_replay_data(outputStream* out) { + GUARDED_VM_ENTRY( + MutexLocker ml(Compile_lock); + dump_replay_data_unsafe(out); + ) +} diff --git a/hotspot/src/share/vm/ci/ciEnv.hpp b/hotspot/src/share/vm/ci/ciEnv.hpp index 01f417d2f9d..b235f3b148b 100644 --- a/hotspot/src/share/vm/ci/ciEnv.hpp +++ b/hotspot/src/share/vm/ci/ciEnv.hpp @@ -452,6 +452,7 @@ public: // Dump the compilation replay data for the ciEnv to the stream. void dump_replay_data(outputStream* out); + void dump_replay_data_unsafe(outputStream* out); }; #endif // SHARE_VM_CI_CIENV_HPP diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index c689efa46d6..d40e460dcf3 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -671,7 +671,6 @@ class StaticFinalFieldPrinter : public FieldClosure { void ciInstanceKlass::dump_replay_data(outputStream* out) { - ASSERT_IN_VM; ResourceMark rm; InstanceKlass* ik = get_instanceKlass(); diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index 486d8c499b6..15bb285a869 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -1247,7 +1247,6 @@ ciMethodBlocks *ciMethod::get_method_blocks() { #undef FETCH_FLAG_FROM_VM void ciMethod::dump_replay_data(outputStream* st) { - ASSERT_IN_VM; ResourceMark rm; Method* method = get_Method(); MethodCounters* mcs = method->method_counters(); diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index c30c6c36437..515401bc17b 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -373,7 +373,6 @@ void ciMethodData::print_impl(outputStream* st) { } void ciMethodData::dump_replay_data(outputStream* out) { - ASSERT_IN_VM; ResourceMark rm; MethodData* mdo = get_MethodData(); Method* method = mdo->method(); diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index 79769aeb3bc..bbf983953b7 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -1050,7 +1050,7 @@ void VMError::report_and_die() { FILE* replay_data_file = os::open(fd, "w"); if (replay_data_file != NULL) { fileStream replay_data_stream(replay_data_file, /*need_close=*/true); - env->dump_replay_data(&replay_data_stream); + env->dump_replay_data_unsafe(&replay_data_stream); out.print_raw("#\n# Compiler replay data is saved as:\n# "); out.print_raw_cr(buffer); } else { From 0059da4a6da836ce449ba201b4ca20c702cd0e93 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 7 Oct 2013 14:12:23 +0400 Subject: [PATCH 023/152] 8024774: assert(_con < t->is_tuple()->cnt()) failed: ProjNode::_con must be in range Reviewed-by: iveresov, roland, kvn, twisti --- hotspot/src/share/vm/opto/parse2.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index c41ca257e62..a910c3ee879 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -268,7 +268,7 @@ public: return adjoinRange(value, value, dest, table_index); } - void print(ciEnv* env) { + void print() { if (is_singleton()) tty->print(" {%d}=>%d", lo(), dest()); else if (lo() == min_jint) @@ -471,8 +471,8 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) // These are the switch destinations hanging off the jumpnode int i = 0; for (SwitchRange* r = lo; r <= hi; r++) { - for (int j = r->lo(); j <= r->hi(); j++, i++) { - Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), j - lowval)); + for (int64 j = r->lo(); j <= r->hi(); j++, i++) { + Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval))); { PreserveJVMState pjvms(this); set_control(input); @@ -632,7 +632,7 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, } tty->print(" "); for( r = lo; r <= hi; r++ ) { - r->print(env()); + r->print(); } tty->print_cr(""); } From bb528dd1d5020902c518901c697cbe42bd366174 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 7 Oct 2013 14:13:28 +0400 Subject: [PATCH 024/152] 8025845: Default methods are unnecessarily marked w/ force_inline directive in some situations Reviewed-by: acorn, kvn --- hotspot/src/share/vm/classfile/defaultMethods.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 2adc6268473..8498223d674 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -1083,7 +1083,6 @@ static Method* new_method( m->set_max_locals(params); m->constMethod()->set_stackmap_data(NULL); m->set_code(code_start); - m->set_force_inline(true); return m; } From f6875dad27c13c133145b97fc7e79636efa14c03 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Tue, 8 Oct 2013 15:33:28 +0200 Subject: [PATCH 025/152] 8024415: Bug in javac Pretty: Wrong precedence in JCConditional trees Fixed precedence and associativity issues with pretty printing of JCConditional expressions. Co-authored-by: Matthew Dempsky Reviewed-by: jfranck --- .../com/sun/tools/javac/tree/Pretty.java | 4 +- langtools/test/tools/javac/tree/T8024415.java | 113 ++++++++++++++++++ 2 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javac/tree/T8024415.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java index 653d9e54eff..9076ce47532 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -782,9 +782,9 @@ public class Pretty extends JCTree.Visitor { public void visitConditional(JCConditional tree) { try { open(prec, TreeInfo.condPrec); - printExpr(tree.cond, TreeInfo.condPrec); + printExpr(tree.cond, TreeInfo.condPrec + 1); print(" ? "); - printExpr(tree.truepart, TreeInfo.condPrec); + printExpr(tree.truepart); print(" : "); printExpr(tree.falsepart, TreeInfo.condPrec); close(prec, TreeInfo.condPrec); diff --git a/langtools/test/tools/javac/tree/T8024415.java b/langtools/test/tools/javac/tree/T8024415.java new file mode 100644 index 00000000000..badd64ff7d8 --- /dev/null +++ b/langtools/test/tools/javac/tree/T8024415.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024415 + * @summary Pretty printing of JCConditional does not follow the precedence and + * associativity rules of JCConditional + * @run testng T8024415 + */ + + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.io.StringWriter; + +import org.testng.annotations.Test; + +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.Pretty; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Names; + + +/* + * Test verifies that the precedence rules of conditional expressions + * (JCConditional) are correct. + */ +@Test +public class T8024415 { + + TreeMaker maker; + JCExpression x; + + + public T8024415() { + Context ctx = new Context(); + JavacFileManager.preRegister(ctx); + maker = TreeMaker.instance(ctx); + Names names = Names.instance(ctx); + x = maker.Ident(names.fromString("x")); + } + + + // JLS 15.25: The conditional operator is syntactically right-associative + // (it groups right-to-left). Thus, a?b:c?d:e?f:g means the same as + // a?b:(c?d:(e?f:g)). + public void testAssociativity() throws IOException { + + JCTree left = maker.Conditional(maker.Conditional(x, x, x), x, x); + JCTree right = maker.Conditional(x, x, maker.Conditional(x, x, x)); + + String prettyLeft = prettyPrint(left); + String prettyRight = prettyPrint(right); + + assertEquals(prettyLeft.replaceAll("\\s", ""), "(x?x:x)?x:x"); + assertEquals(prettyRight.replaceAll("\\s", ""), "x?x:x?x:x"); + + } + + + // The true-part of of a conditional expression is surrounded by ? and : + // and can thus always be parsed unambiguously without surrounding + // parentheses. + public void testPrecedence() throws IOException { + + JCTree left = maker.Conditional(maker.Assign(x, x), x, x); + JCTree middle = maker.Conditional(x, maker.Assign(x, x), x); + JCTree right = maker.Conditional(x, x, maker.Assign(x, x)); + + String prettyLeft = prettyPrint(left); + String prettyMiddle = prettyPrint(middle); + String prettyRight = prettyPrint(right); + + assertEquals(prettyLeft.replaceAll("\\s", ""), "(x=x)?x:x"); + assertEquals(prettyMiddle.replaceAll("\\s", ""), "x?x=x:x"); + assertEquals(prettyRight.replaceAll("\\s", ""), "x?x:(x=x)"); + + } + + + // Helper method + private static String prettyPrint(JCTree tree) throws IOException { + StringWriter sw = new StringWriter(); + new Pretty(sw, true).printExpr(tree); + return sw.toString(); + } + +} From 3fc4c7060d0b6eab919b1a8c2afd8bc478da84ed Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Tue, 8 Oct 2013 19:57:28 -0700 Subject: [PATCH 026/152] 8007923: Tests on references fails Reviewed-by: kvn, iveresov --- hotspot/src/share/vm/ci/ciKlass.cpp | 8 +++++--- hotspot/src/share/vm/opto/escape.cpp | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciKlass.cpp b/hotspot/src/share/vm/ci/ciKlass.cpp index ee5e2700ffc..2a4a25acded 100644 --- a/hotspot/src/share/vm/ci/ciKlass.cpp +++ b/hotspot/src/share/vm/ci/ciKlass.cpp @@ -66,7 +66,9 @@ ciKlass::ciKlass(ciSymbol* name, BasicType bt) : ciType(bt) { // ------------------------------------------------------------------ // ciKlass::is_subtype_of bool ciKlass::is_subtype_of(ciKlass* that) { - assert(is_loaded() && that->is_loaded(), "must be loaded"); + assert(this->is_loaded(), err_msg("must be loaded: %s", this->name()->as_quoted_ascii())); + assert(that->is_loaded(), err_msg("must be loaded: %s", that->name()->as_quoted_ascii())); + // Check to see if the klasses are identical. if (this == that) { return true; @@ -83,8 +85,8 @@ bool ciKlass::is_subtype_of(ciKlass* that) { // ------------------------------------------------------------------ // ciKlass::is_subclass_of bool ciKlass::is_subclass_of(ciKlass* that) { - assert(is_loaded() && that->is_loaded(), "must be loaded"); - // Check to see if the klasses are identical. + assert(this->is_loaded(), err_msg("must be loaded: %s", this->name()->as_quoted_ascii())); + assert(that->is_loaded(), err_msg("must be loaded: %s", that->name()->as_quoted_ascii())); VM_ENTRY_MARK; Klass* this_klass = get_Klass(); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index c95226f110c..50afded6a92 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -780,6 +780,7 @@ void ConnectionGraph::add_call_node(CallNode* call) { } } else { // Allocate instance if (cik->is_subclass_of(_compile->env()->Thread_klass()) || + cik->is_subclass_of(_compile->env()->Reference_klass()) || !cik->is_instance_klass() || // StressReflectiveCode cik->as_instance_klass()->has_finalizer()) { es = PointsToNode::GlobalEscape; From 1ed2372816166e7127382023e5ede31494b76ade Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 9 Oct 2013 10:47:47 +0200 Subject: [PATCH 027/152] 8026112: Function("with(x ? 1e81 : (x2.constructor = 0.1)){}") throws AssertionError: double is not compatible with object Reviewed-by: lagergren, hannesw --- .../internal/codegen/CodeGenerator.java | 4 +-- nashorn/test/script/basic/JDK-8026112.js | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026112.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 5f7f596de03..8ce908d8197 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -2893,7 +2893,7 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Wed, 9 Oct 2013 13:00:20 +0200 Subject: [PATCH 028/152] 8013830: [parfait] Uninitialised pointer 'Reachblock' may be used as argument Replace uninitialised pointer with NULL at argument. Reviewed-by: kvn, roland, twisti --- hotspot/src/share/vm/opto/reg_split.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp index 2c4ad874ffe..f58a380edd7 100644 --- a/hotspot/src/share/vm/opto/reg_split.cpp +++ b/hotspot/src/share/vm/opto/reg_split.cpp @@ -375,6 +375,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint } if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).reg() >= LRG::SPILL_REG) { + assert(Reachblock != NULL, "Reachblock must be non-NULL"); Node *rdef = Reachblock[lrg2reach[lidx]]; if (rdef) { spill->set_req(i, rdef); @@ -1336,7 +1337,8 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { _lrg_map.find(pred->get_node(insert - 1)) >= lrgs_before_phi_split) { insert--; } - def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false); + // since the def cannot contain any live range input, we can pass in NULL as Reachlock parameter + def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, NULL, false); if (!def) { return 0; // Bail out } From 7de3ec870defa263cff1aa9dbea6cd4b9f56d2bc Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 9 Oct 2013 13:06:49 +0200 Subject: [PATCH 029/152] 8025141: java.lang.ClassFormatError: Illegal field modifiers in class (...) Should not generate non-public $assertionsDisabled field into interfaces Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/comp/Lower.java | 28 ++++- .../javac/defaultMethods/Assertions.java | 102 ++++++++++++++++++ ...ChangeAssertionsStateAfterInitialized.java | 43 ++++++++ 3 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javac/defaultMethods/Assertions.java create mode 100644 langtools/test/tools/javac/defaultMethods/CannotChangeAssertionsStateAfterInitialized.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 51588257c9b..c362c77b15a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2172,6 +2172,18 @@ public class Lower extends TreeTranslator { * Code for enabling/disabling assertions. *************************************************************************/ + private ClassSymbol assertionsDisabledClassCache; + + /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces. + */ + private ClassSymbol assertionsDisabledClass() { + if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache; + + assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC, outermostClassDef.sym).sym; + + return assertionsDisabledClassCache; + } + // This code is not particularly robust if the user has // previously declared a member named '$assertionsDisabled'. // The same faulty idiom also appears in the translation of @@ -2182,8 +2194,9 @@ public class Lower extends TreeTranslator { // Outermost class may be either true class or an interface. ClassSymbol outermostClass = outermostClassDef.sym; - // note that this is a class, as an interface can't contain a statement. - ClassSymbol container = currentClass; + //only classes can hold a non-public field, look for a usable one: + ClassSymbol container = !currentClass.isInterface() ? currentClass : + assertionsDisabledClass(); VarSymbol assertDisabledSym = (VarSymbol)lookupSynthetic(dollarAssertionsDisabled, @@ -2208,6 +2221,16 @@ public class Lower extends TreeTranslator { JCVariableDecl assertDisabledDef = make.VarDef(assertDisabledSym, notStatus); containerDef.defs = containerDef.defs.prepend(assertDisabledDef); + + if (currentClass.isInterface()) { + //need to load the assertions enabled/disabled state while + //initializing the interface: + JCClassDecl currentClassDef = classDef(currentClass); + make_at(currentClassDef.pos()); + JCStatement dummy = make.If(make.QualIdent(assertDisabledSym), make.Skip(), null); + JCBlock clinit = make.Block(STATIC, List.of(dummy)); + currentClassDef.defs = currentClassDef.defs.prepend(clinit); + } } make_at(pos); return makeUnary(NOT, make.Ident(assertDisabledSym)); @@ -3929,6 +3952,7 @@ public class Lower extends TreeTranslator { accessConstrTags = null; accessed = null; enumSwitchMap.clear(); + assertionsDisabledClassCache = null; } return translated.toList(); } diff --git a/langtools/test/tools/javac/defaultMethods/Assertions.java b/langtools/test/tools/javac/defaultMethods/Assertions.java new file mode 100644 index 00000000000..61882bacebc --- /dev/null +++ b/langtools/test/tools/javac/defaultMethods/Assertions.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/* + * @test + * @bug 8025141 + * @summary Interfaces must not contain non-public fields, ensure $assertionsDisabled + * is not generated into an interface + * @compile Assertions.java + * @run main/othervm -da test.Assertions + * @run main/othervm -ea:test.Assertions test.Assertions Inner + * @run main/othervm -ea:test.Outer test.Assertions Outer + * @run main/othervm -ea:test.Another test.Assertions Another.Inner + * @run main/othervm -ea:test... test.Assertions Inner Outer Another.Inner + */ + +public class Assertions { + interface Inner { + default void testInner() { + assert false; + } + } + + static class InnerImpl implements Inner {} + + static class OuterImpl implements Outer {} + + static class AnotherInnerImpl implements Another.Inner {} + + public static void main(String... args) { + Set shouldThrowAssert = new HashSet(Arrays.asList(args)); + try { + new InnerImpl().testInner(); + if (shouldThrowAssert.contains("Inner")) { + throw new IllegalStateException("AssertionError expected, but not thrown."); + } + } catch (AssertionError e) { + if (!shouldThrowAssert.contains("Inner")) { + throw new IllegalStateException("AssertionError not expected, but thrown."); + } + } + try { + new OuterImpl().testOuter(); + if (shouldThrowAssert.contains("Outer")) { + throw new IllegalStateException("AssertionError expected, but not thrown."); + } + } catch (AssertionError e) { + if (!shouldThrowAssert.contains("Outer")) { + throw new IllegalStateException("AssertionError not expected, but thrown."); + } + } + try { + new AnotherInnerImpl().testAnotherInner(); + if (shouldThrowAssert.contains("Another.Inner")) { + throw new IllegalStateException("AssertionError expected, but not thrown."); + } + } catch (AssertionError e) { + if (!shouldThrowAssert.contains("Another.Inner")) { + throw new IllegalStateException("AssertionError not expected, but thrown."); + } + } + } +} + +interface Outer { + default void testOuter() { + assert false; + } +} + +@interface Another { + interface Inner { + default void testAnotherInner() { + assert false; + } + } +} diff --git a/langtools/test/tools/javac/defaultMethods/CannotChangeAssertionsStateAfterInitialized.java b/langtools/test/tools/javac/defaultMethods/CannotChangeAssertionsStateAfterInitialized.java new file mode 100644 index 00000000000..b6dbdb9c55a --- /dev/null +++ b/langtools/test/tools/javac/defaultMethods/CannotChangeAssertionsStateAfterInitialized.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025141 + * @summary Ensure the assertion status cannot be changed once the class is initialized + * @compile CannotChangeAssertionsStateAfterInitialized.java + * @run main/othervm -da CannotChangeAssertionsStateAfterInitialized + */ + +public interface CannotChangeAssertionsStateAfterInitialized { + default void m() { + assert false; + } + + public static void main(String[] args) { + ClassLoader cl = CannotChangeAssertionsStateAfterInitialized.class.getClassLoader(); + cl.setClassAssertionStatus(CannotChangeAssertionsStateAfterInitialized.class.getName(), true); + new CannotChangeAssertionsStateAfterInitialized() {}.m(); + } + +} From 5ec0ba7c4798facecd3c79673a0749d98be2d191 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 9 Oct 2013 13:09:31 +0200 Subject: [PATCH 030/152] 8025087: Annotation processing api returns default modifier for interface static method ClassReader must not set Flags.DEFAULT for interface static methods Reviewed-by: vromero, jjg --- langtools/make/build.xml | 6 +- .../com/sun/tools/javac/jvm/ClassReader.java | 10 ++- .../tools/javac/resources/compiler.properties | 9 ++ .../javac/defaultMethods/BadClassfile.java | 89 +++++++++++++++++++ .../tools/javac/diags/examples.not-yet.txt | 1 - .../InvalidDefaultInterface.java | 33 +++++++ .../processors/CreateBadClassFile.java | 85 ++++++++++++++++++ .../InvalidStaticInterface.java | 33 +++++++ .../processors/CreateBadClassFile.java | 86 ++++++++++++++++++ .../model/element/TestExecutableElement.java | 37 ++++---- 10 files changed, 365 insertions(+), 24 deletions(-) create mode 100644 langtools/test/tools/javac/defaultMethods/BadClassfile.java create mode 100644 langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java create mode 100644 langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java create mode 100644 langtools/test/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java create mode 100644 langtools/test/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java diff --git a/langtools/make/build.xml b/langtools/make/build.xml index d242e722141..ddd0bc44bfe 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -360,7 +360,7 @@ datafile="${build.coverage.dir}/cobertura.ser"/> - + @@ -370,7 +370,7 @@ destdir="${build.dir}/diag-examples/classes" includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java,DocCommentProcessor.java" sourcepath="" - classpath="${dist.lib.dir}/javac.jar" + classpath="${dist.lib.dir}/javac.jar;${dist.lib.dir}/javap.jar" includeAntRuntime="no" debug="${javac.debug}" debuglevel="${javac.debuglevel}"> @@ -379,7 +379,7 @@ diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 397069589ff..8b3ee47bf70 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1993,11 +1993,15 @@ public class ClassReader { (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) { if (majorVersion > Target.JDK1_8.majorVersion || (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) { - currentOwner.flags_field |= DEFAULT; - flags |= DEFAULT | ABSTRACT; + if ((flags & STATIC) == 0) { + currentOwner.flags_field |= DEFAULT; + flags |= DEFAULT | ABSTRACT; + } } else { //protect against ill-formed classfiles - throw new CompletionFailure(currentOwner, "default method found in pre JDK 8 classfile"); + throw badClassFile((flags & STATIC) == 0 ? "invalid.default.interface" : "invalid.static.interface", + Integer.toString(majorVersion), + Integer.toString(minorVersion)); } } if (name == names.init && currentOwner.hasOuterInstance()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index f8174d4633e..2fc6ab75a80 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1699,6 +1699,7 @@ compiler.err.cant.access=\ cannot access {0}\n\ {1} +# 0: file name, 1: message segment compiler.misc.bad.class.file.header=\ bad class file: {0}\n\ {1}\n\ @@ -1744,6 +1745,14 @@ compiler.misc.class.file.wrong.class=\ compiler.misc.class.file.not.found=\ class file for {0} not found +# 0: classfile major version, 1: classfile minor version +compiler.misc.invalid.default.interface=\ + default method found in version {0}.{1} classfile + +# 0: classfile major version, 1: classfile minor version +compiler.misc.invalid.static.interface=\ + static method found in version {0}.{1} classfile + # 0: name compiler.misc.file.doesnt.contain.class=\ file does not contain class {0} diff --git a/langtools/test/tools/javac/defaultMethods/BadClassfile.java b/langtools/test/tools/javac/defaultMethods/BadClassfile.java new file mode 100644 index 00000000000..424d3acf102 --- /dev/null +++ b/langtools/test/tools/javac/defaultMethods/BadClassfile.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025087 + * @summary Verify that pre-JDK8 classfiles with default and/or static methods + * are refused correctly. + * @build BadClassfile + * @run main BadClassfile + */ + +import com.sun.tools.classfile.*; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.jvm.ClassReader.BadClassFile; +import com.sun.tools.javac.jvm.Target; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.JCDiagnostic; +import java.io.File; +import java.util.Arrays; +import java.util.Objects; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; + +public class BadClassfile { + public static void main(String... args) throws Exception { + test("BadClassfile$DefaultMethodTest", "compiler.misc.invalid.default.interface"); + test("BadClassfile$StaticMethodTest", "compiler.misc.invalid.static.interface"); + } + + private static void test(String classname, String expected) throws Exception { + File classfile = new File(System.getProperty("test.classes", "."), classname + ".class"); + ClassFile cf = ClassFile.read(classfile); + + cf = new ClassFile(cf.magic, Target.JDK1_7.minorVersion, + Target.JDK1_7.majorVersion, cf.constant_pool, cf.access_flags, + cf.this_class, cf.super_class, cf.interfaces, cf.fields, + cf.methods, cf.attributes); + + new ClassWriter().write(cf, classfile); + + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + JavacTaskImpl task = (JavacTaskImpl) c.getTask(null, null, null, Arrays.asList("-classpath", System.getProperty("test.classes", ".")), null, null); + + try { + Symbol clazz = com.sun.tools.javac.main.JavaCompiler.instance(task.getContext()).resolveIdent(classname); + + clazz.complete(); + } catch (BadClassFile f) { + JCDiagnostic embeddedDiag = (JCDiagnostic) f.diag.getArgs()[1]; + assertEquals(expected, embeddedDiag.getCode()); + assertEquals(Integer.toString(Target.JDK1_7.majorVersion), embeddedDiag.getArgs()[0]); + assertEquals(Integer.toString(Target.JDK1_7.minorVersion), embeddedDiag.getArgs()[1]); + } + } + + private static void assertEquals(Object expected, Object actual) { + Assert.check(Objects.equals(expected, actual), + "expected: " + expected + ", but was: " + actual); + } + + interface DefaultMethodTest { + default void test() { } + } + interface StaticMethodTest { + static void test() { } + } +} diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index 2e442f38943..2676b71929b 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -40,7 +40,6 @@ compiler.err.type.var.more.than.once # UNUSED compiler.err.type.var.more.than.once.in.result # UNUSED compiler.err.unexpected.type compiler.err.unsupported.cross.fp.lit # Scanner: host system dependent -compiler.misc.bad.class.file.header # bad class file compiler.misc.bad.class.signature # bad class file compiler.misc.bad.const.pool.tag # bad class file compiler.misc.bad.const.pool.tag.at # bad class file diff --git a/langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java b/langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java new file mode 100644 index 00000000000..a8b1d4423df --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.misc.invalid.default.interface +// key: compiler.misc.bad.class.file.header +// key: compiler.err.cant.access +// options: -processor CreateBadClassFile + +/* The annotation processor will create an invalid classfile with version 51.0 + * and a non-abstract method in an interface. Loading the classfile will produce + * the diagnostic. + */ +class InvalidDefaultInterface { } diff --git a/langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java b/langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java new file mode 100644 index 00000000000..1f37bfabb5d --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info; +import com.sun.tools.classfile.ConstantPool.CPInfo; +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.*; + +/* Create an invalid classfile with version 51.0 and a non-abstract method in an interface.*/ +@SupportedAnnotationTypes("*") +public class CreateBadClassFile extends AbstractProcessor { + public boolean process(Set elems, RoundEnvironment renv) { + if (++round == 1) { + ConstantPool cp = new ConstantPool(new CPInfo[] { + new CONSTANT_Utf8_info(""), //0 + new CONSTANT_Utf8_info("Test"), //1 + new CONSTANT_Class_info(null, 1), //2 + new CONSTANT_Utf8_info("java/lang/Object"), //3 + new CONSTANT_Class_info(null, 3), //4 + new CONSTANT_Utf8_info("test"), //5 + new CONSTANT_Utf8_info("()V"), //6 + }); + ClassFile cf = new ClassFile(0xCAFEBABE, + 0, + 51, + cp, + new AccessFlags(AccessFlags.ACC_ABSTRACT | + AccessFlags.ACC_INTERFACE | + AccessFlags.ACC_PUBLIC), + 2, + 4, + new int[0], + new Field[0], + new Method[] { + //creating non-abstract method in 51.0 classfile: + new Method(new AccessFlags(AccessFlags.ACC_PUBLIC), + 5, + new Descriptor(6), + new Attributes(cp, new Attribute[0])) + }, + new Attributes(cp, new Attribute[0])); + try { + JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test"); + try (OutputStream out = clazz.openOutputStream()) { + new ClassWriter().write(cf, out); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return false; + } + + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + int round = 0; +} diff --git a/langtools/test/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java b/langtools/test/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java new file mode 100644 index 00000000000..3d5ff005e9f --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.misc.invalid.static.interface +// key: compiler.misc.bad.class.file.header +// key: compiler.err.cant.access +// options: -processor CreateBadClassFile + +/* The annotation processor will create an invalid classfile with version 51.0 + * and a static method in an interface. Loading the classfile will produce + * the diagnostic. + */ +class InvalidDefaultInterface { } diff --git a/langtools/test/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java b/langtools/test/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java new file mode 100644 index 00000000000..acd362cbf96 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info; +import com.sun.tools.classfile.ConstantPool.CPInfo; +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.*; + +/* Create an invalid classfile with version 51.0 and a static method in an interface.*/ +@SupportedAnnotationTypes("*") +public class CreateBadClassFile extends AbstractProcessor { + public boolean process(Set elems, RoundEnvironment renv) { + if (++round == 1) { + ConstantPool cp = new ConstantPool(new CPInfo[] { + new CONSTANT_Utf8_info(""), //0 + new CONSTANT_Utf8_info("Test"), //1 + new CONSTANT_Class_info(null, 1), //2 + new CONSTANT_Utf8_info("java/lang/Object"), //3 + new CONSTANT_Class_info(null, 3), //4 + new CONSTANT_Utf8_info("test"), //5 + new CONSTANT_Utf8_info("()V"), //6 + }); + ClassFile cf = new ClassFile(0xCAFEBABE, + 0, + 51, + cp, + new AccessFlags(AccessFlags.ACC_ABSTRACT | + AccessFlags.ACC_INTERFACE | + AccessFlags.ACC_PUBLIC), + 2, + 4, + new int[0], + new Field[0], + new Method[] { + //creating static method in 51.0 classfile: + new Method(new AccessFlags(AccessFlags.ACC_PUBLIC | + AccessFlags.ACC_STATIC), + 5, + new Descriptor(6), + new Attributes(cp, new Attribute[0])) + }, + new Attributes(cp, new Attribute[0])); + try { + JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test"); + try (OutputStream out = clazz.openOutputStream()) { + new ClassWriter().write(cf, out); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return false; + } + + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + int round = 0; +} diff --git a/langtools/test/tools/javac/processing/model/element/TestExecutableElement.java b/langtools/test/tools/javac/processing/model/element/TestExecutableElement.java index 35aae46bdd8..d40b1433a54 100644 --- a/langtools/test/tools/javac/processing/model/element/TestExecutableElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestExecutableElement.java @@ -23,54 +23,57 @@ /* * @test - * @bug 8005046 8011052 - * @summary Test basic properties of javax.lang.element.Element + * @bug 8005046 8011052 8025087 + * @summary Test basic properties of javax.lang.element.ExecutableElement * @author Joseph D. Darcy * @library /tools/javac/lib * @build JavacTestingAbstractProcessor TestExecutableElement - * @compile -processor TestExecutableElement -proc:only TestExecutableElement.java + * @compile -processor TestExecutableElement -proc:only -AexpectedMethodCount=7 TestExecutableElement.java + * @compile/process -processor TestExecutableElement -proc:only -AexpectedMethodCount=3 ProviderOfDefault */ import java.lang.annotation.*; import java.util.Formatter; import java.util.Set; -import java.util.Objects; import java.util.regex.*; import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import static javax.lang.model.SourceVersion.*; import javax.lang.model.element.*; -import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.*; import static javax.tools.Diagnostic.Kind.*; -import static javax.tools.StandardLocation.*; /** * Test some basic workings of javax.lang.element.ExecutableElement */ +@SupportedOptions("expectedMethodCount") public class TestExecutableElement extends JavacTestingAbstractProcessor implements ProviderOfDefault { + private int seenMethods = 0; @IsDefault(false) public boolean process(Set annotations, RoundEnvironment roundEnv) { - int errors = 0; if (!roundEnv.processingOver()) { - boolean hasRun = false; for (Element element : roundEnv.getRootElements()) { for (ExecutableElement method : methodsIn(element.getEnclosedElements())) { - hasRun = true; - errors += checkIsDefault(method); + checkIsDefault(method); + seenMethods++; } } + } else { + String expectedMethodCountStr = processingEnv.getOptions().get("expectedMethodCount"); + if (expectedMethodCountStr == null) { + messager.printMessage(ERROR, "No expected method count specified."); + } else { + int expectedMethodCount = Integer.parseInt(expectedMethodCountStr); - if (!hasRun) { - messager.printMessage(ERROR, "No test cases run; test fails."); + if (seenMethods != expectedMethodCount) { + messager.printMessage(ERROR, "Wrong number of seen methods: " + seenMethods); + } } } return true; } @IsDefault(false) - int checkIsDefault(ExecutableElement method) { + void checkIsDefault(ExecutableElement method) { System.out.println("Testing " + method); IsDefault expectedIsDefault = method.getAnnotation(IsDefault.class); @@ -116,9 +119,7 @@ public class TestExecutableElement extends JavacTestingAbstractProcessor impleme expectedDefault, methodIsDefault).toString(), method); - return 1; } - return 0; } } @@ -142,4 +143,6 @@ interface ProviderOfDefault { @IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$") default strictfp void quux() {}; + @IsDefault(false) + static void statik() {} } From a7261c57e053581c021af981b418269bf6303f98 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 9 Oct 2013 13:26:23 +0200 Subject: [PATCH 031/152] 8026125: Array.prototype.slice.call(Java.type("java.util.HashMap")) throws ClassCastException: jdk.internal.dynalink.beans.StaticClass cannot be cast to jdk.nashorn.internal.runtime.ScriptObject Reviewed-by: hannesw, jlaskey --- .../nashorn/internal/objects/NativeArray.java | 4 +++ nashorn/test/script/basic/JDK-8026125.js | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 nashorn/test/script/basic/JDK-8026125.js diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java index fa325753f32..37b6355bd00 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java @@ -851,6 +851,10 @@ public final class NativeArray extends ScriptObject { @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object slice(final Object self, final Object start, final Object end) { final Object obj = Global.toObject(self); + if (!(obj instanceof ScriptObject)) { + return ScriptRuntime.UNDEFINED; + } + final ScriptObject sobj = (ScriptObject)obj; final long len = JSType.toUint32(sobj.getLength()); final long relativeStart = JSType.toLong(start); diff --git a/nashorn/test/script/basic/JDK-8026125.js b/nashorn/test/script/basic/JDK-8026125.js new file mode 100644 index 00000000000..bb3a43d8040 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026125.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026125: Array.prototype.slice.call(Java.type("java.util.HashMap")) throws ClassCastException: jdk.internal.dynalink.beans.StaticClass cannot be cast to jdk.nashorn.internal.runtime.ScriptObject + * + * @test + * @run + */ + +Array.prototype.splice.call(Java.type("java.util.HashMap")) +Array.prototype.slice.call(Java.type("java.util.HashMap")) From 3ef5f027ce454e851c18d3fdac6d52dc7fccc76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 9 Oct 2013 14:50:39 +0200 Subject: [PATCH 032/152] 8026008: Constant folding removes var statement Reviewed-by: sundar, jlaskey --- .../internal/codegen/FoldConstants.java | 33 +++++++++-- nashorn/test/script/basic/JDK-8026008.js | 55 +++++++++++++++++++ .../test/script/basic/JDK-8026008.js.EXPECTED | 3 + 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026008.js create mode 100644 nashorn/test/script/basic/JDK-8026008.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java index 9a2aafa0d0d..59362fa2a29 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java @@ -25,6 +25,8 @@ package jdk.nashorn.internal.codegen; +import java.util.ArrayList; +import java.util.List; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; @@ -37,8 +39,10 @@ import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.Statement; import jdk.nashorn.internal.ir.TernaryNode; import jdk.nashorn.internal.ir.UnaryNode; +import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.JSType; @@ -89,11 +93,21 @@ final class FoldConstants extends NodeVisitor { public Node leaveIfNode(final IfNode ifNode) { final Node test = ifNode.getTest(); if (test instanceof LiteralNode.PrimitiveLiteralNode) { - final Block shortCut = ((LiteralNode.PrimitiveLiteralNode)test).isTrue() ? ifNode.getPass() : ifNode.getFail(); - if (shortCut != null) { - return new BlockStatement(ifNode.getLineNumber(), shortCut); + final boolean isTrue = ((LiteralNode.PrimitiveLiteralNode)test).isTrue(); + final Block executed = isTrue ? ifNode.getPass() : ifNode.getFail(); + final Block dropped = isTrue ? ifNode.getFail() : ifNode.getPass(); + final List statements = new ArrayList<>(); + + if (executed != null) { + statements.addAll(executed.getStatements()); // Get statements form executed branch } - return new EmptyNode(ifNode); + if (dropped != null) { + extractVarNodes(dropped, statements); // Get var-nodes from non-executed branch + } + if (statements.isEmpty()) { + return new EmptyNode(ifNode); + } + return BlockStatement.createReplacement(ifNode, ifNode.getFinish(), statements); } return ifNode; } @@ -131,6 +145,17 @@ final class FoldConstants extends NodeVisitor { protected abstract LiteralNode eval(); } + private static void extractVarNodes(final Block block, final List statements) { + final LexicalContext lc = new LexicalContext(); + block.accept(lc, new NodeVisitor(lc) { + @Override + public boolean enterVarNode(VarNode varNode) { + statements.add(varNode.setInit(null)); + return false; + } + }); + } + private static class UnaryNodeConstantEvaluator extends ConstantEvaluator { UnaryNodeConstantEvaluator(final UnaryNode parent) { super(parent); diff --git a/nashorn/test/script/basic/JDK-8026008.js b/nashorn/test/script/basic/JDK-8026008.js new file mode 100644 index 00000000000..20c1d5f0290 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026008.js @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026008: Constant folding removes var statement + * + * @test + * @run + */ + +if (false) { + var x1 = 10; + if (false) { + var x2; + } +} else { + print(x1, x2); +} + +if (undefined) { + var z1; + if (null) { + var z2; + } +} + +print(z1, z2); + +if (1) { + print(y1, y2); +} else if (0) { + var y1 = 1; +} else { + var y2 = 2 +} diff --git a/nashorn/test/script/basic/JDK-8026008.js.EXPECTED b/nashorn/test/script/basic/JDK-8026008.js.EXPECTED new file mode 100644 index 00000000000..6bbb6d93f19 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026008.js.EXPECTED @@ -0,0 +1,3 @@ +undefined undefined +undefined undefined +undefined undefined From cbd0e9bf96e7f4ce5ae532f81160263a92b59f2e Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 9 Oct 2013 16:32:21 +0200 Subject: [PATCH 033/152] 8023657: New type profiling points: arguments to call X86 interpreter and c1 type profiling for arguments at calls Reviewed-by: kvn, twisti --- .../cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 4 + hotspot/src/cpu/sparc/vm/globals_sparc.hpp | 2 + .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 155 +++++ hotspot/src/cpu/x86/vm/globals_x86.hpp | 2 + hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp | 92 +++ hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp | 2 + hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp | 96 +++ hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp | 2 + hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp | 1 + .../src/cpu/x86/vm/templateTable_x86_32.cpp | 8 + .../src/cpu/x86/vm/templateTable_x86_64.cpp | 8 + hotspot/src/share/vm/c1/c1_Compilation.cpp | 11 + hotspot/src/share/vm/c1/c1_Compilation.hpp | 2 + hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 67 +- hotspot/src/share/vm/c1/c1_GraphBuilder.hpp | 5 +- hotspot/src/share/vm/c1/c1_Instruction.cpp | 83 +-- hotspot/src/share/vm/c1/c1_Instruction.hpp | 101 ++- .../src/share/vm/c1/c1_InstructionPrinter.cpp | 8 + hotspot/src/share/vm/c1/c1_LIR.cpp | 26 + hotspot/src/share/vm/c1/c1_LIR.hpp | 51 +- hotspot/src/share/vm/c1/c1_LIRAssembler.hpp | 1 + hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 112 ++++ hotspot/src/share/vm/c1/c1_LIRGenerator.hpp | 2 + hotspot/src/share/vm/c1/c1_Optimizer.cpp | 9 +- .../share/vm/c1/c1_RangeCheckElimination.hpp | 2 +- hotspot/src/share/vm/ci/ciClassList.hpp | 1 + hotspot/src/share/vm/ci/ciInstanceKlass.hpp | 7 + hotspot/src/share/vm/ci/ciKlass.hpp | 3 + hotspot/src/share/vm/ci/ciMethodData.cpp | 68 +- hotspot/src/share/vm/ci/ciMethodData.hpp | 116 +++- hotspot/src/share/vm/ci/ciObjArrayKlass.cpp | 13 + hotspot/src/share/vm/ci/ciObjArrayKlass.hpp | 2 + hotspot/src/share/vm/ci/ciStreams.hpp | 24 +- hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp | 4 + hotspot/src/share/vm/oops/methodData.cpp | 293 ++++++++- hotspot/src/share/vm/oops/methodData.hpp | 603 +++++++++++++++--- hotspot/src/share/vm/runtime/globals.hpp | 8 +- hotspot/src/share/vm/runtime/java.cpp | 4 + hotspot/src/share/vm/runtime/signature.cpp | 10 + hotspot/src/share/vm/runtime/signature.hpp | 3 + 40 files changed, 1773 insertions(+), 238 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index cb4c04a388b..115302c9e1a 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -3100,6 +3100,10 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } } +void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { + fatal("Type profiling not implemented on this platform"); +} + void LIR_Assembler::align_backward_branch_target() { __ align(OptoLoopAlignment); } diff --git a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp index acffc90f2cf..ecc6eb61524 100644 --- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp @@ -76,6 +76,8 @@ define_pd_global(bool, UseMembar, false); // GC Ergo Flags define_pd_global(uintx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread +define_pd_global(uintx, TypeProfileLevel, 0); + #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \ \ product(intx, UseVIS, 99, \ diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 94c2c39d26f..5ed890cfb4a 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -3632,6 +3632,161 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } } +void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { + Register obj = op->obj()->as_register(); + Register tmp = op->tmp()->as_pointer_register(); + Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); + ciKlass* exact_klass = op->exact_klass(); + intptr_t current_klass = op->current_klass(); + bool not_null = op->not_null(); + bool no_conflict = op->no_conflict(); + + Label update, next, none; + + bool do_null = !not_null; + bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; + bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; + + assert(do_null || do_update, "why are we here?"); + assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); + + __ verify_oop(obj); + + if (tmp != obj) { + __ mov(tmp, obj); + } + if (do_null) { + __ testptr(tmp, tmp); + __ jccb(Assembler::notZero, update); + if (!TypeEntries::was_null_seen(current_klass)) { + __ orptr(mdo_addr, TypeEntries::null_seen); + } + if (do_update) { +#ifndef ASSERT + __ jmpb(next); + } +#else + __ jmp(next); + } + } else { + __ testptr(tmp, tmp); + __ jccb(Assembler::notZero, update); + __ stop("unexpect null obj"); +#endif + } + + __ bind(update); + + if (do_update) { +#ifdef ASSERT + if (exact_klass != NULL) { + Label ok; + __ load_klass(tmp, tmp); + __ push(tmp); + __ mov_metadata(tmp, exact_klass->constant_encoding()); + __ cmpptr(tmp, Address(rsp, 0)); + __ jccb(Assembler::equal, ok); + __ stop("exact klass and actual klass differ"); + __ bind(ok); + __ pop(tmp); + } +#endif + if (!no_conflict) { + if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { + if (exact_klass != NULL) { + __ mov_metadata(tmp, exact_klass->constant_encoding()); + } else { + __ load_klass(tmp, tmp); + } + + __ xorptr(tmp, mdo_addr); + __ testptr(tmp, TypeEntries::type_klass_mask); + // klass seen before, nothing to do. The unknown bit may have been + // set already but no need to check. + __ jccb(Assembler::zero, next); + + __ testptr(tmp, TypeEntries::type_unknown); + __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. + + if (TypeEntries::is_type_none(current_klass)) { + __ cmpptr(mdo_addr, 0); + __ jccb(Assembler::equal, none); + __ cmpptr(mdo_addr, TypeEntries::null_seen); + __ jccb(Assembler::equal, none); + // There is a chance that the checks above (re-reading profiling + // data from memory) fail if another thread has just set the + // profiling to this obj's klass + __ xorptr(tmp, mdo_addr); + __ testptr(tmp, TypeEntries::type_klass_mask); + __ jccb(Assembler::zero, next); + } + } else { + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); + + __ movptr(tmp, mdo_addr); + __ testptr(tmp, TypeEntries::type_unknown); + __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. + } + + // different than before. Cannot keep accurate profile. + __ orptr(mdo_addr, TypeEntries::type_unknown); + + if (TypeEntries::is_type_none(current_klass)) { + __ jmpb(next); + + __ bind(none); + // first time here. Set profile type. + __ movptr(mdo_addr, tmp); + } + } else { + // There's a single possible klass at this profile point + assert(exact_klass != NULL, "should be"); + if (TypeEntries::is_type_none(current_klass)) { + __ mov_metadata(tmp, exact_klass->constant_encoding()); + __ xorptr(tmp, mdo_addr); + __ testptr(tmp, TypeEntries::type_klass_mask); +#ifdef ASSERT + __ jcc(Assembler::zero, next); + + { + Label ok; + __ push(tmp); + __ cmpptr(mdo_addr, 0); + __ jcc(Assembler::equal, ok); + __ cmpptr(mdo_addr, TypeEntries::null_seen); + __ jcc(Assembler::equal, ok); + // may have been set by another thread + __ mov_metadata(tmp, exact_klass->constant_encoding()); + __ xorptr(tmp, mdo_addr); + __ testptr(tmp, TypeEntries::type_mask); + __ jcc(Assembler::zero, ok); + + __ stop("unexpected profiling mismatch"); + __ bind(ok); + __ pop(tmp); + } +#else + __ jccb(Assembler::zero, next); +#endif + // first time here. Set profile type. + __ movptr(mdo_addr, tmp); + } else { + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); + + __ movptr(tmp, mdo_addr); + __ testptr(tmp, TypeEntries::type_unknown); + __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. + + __ orptr(mdo_addr, TypeEntries::type_unknown); + } + } + + __ bind(next); + } +} + void LIR_Assembler::emit_delay(LIR_OpDelay*) { Unimplemented(); } diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp index c47f7d1c193..8e8c42fabb6 100644 --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp @@ -79,6 +79,8 @@ define_pd_global(bool, UseMembar, false); // GC Ergo Flags define_pd_global(uintx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread +define_pd_global(uintx, TypeProfileLevel, 1); + #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \ \ develop(bool, IEEEPrecision, true, \ diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp index 0e7f483a649..1a602ae8c09 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp @@ -1046,6 +1046,98 @@ void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) { } } +void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) { + Label update, next, none; + + verify_oop(obj); + + testptr(obj, obj); + jccb(Assembler::notZero, update); + orptr(mdo_addr, TypeEntries::null_seen); + jmpb(next); + + bind(update); + load_klass(obj, obj); + + xorptr(obj, mdo_addr); + testptr(obj, TypeEntries::type_klass_mask); + jccb(Assembler::zero, next); // klass seen before, nothing to + // do. The unknown bit may have been + // set already but no need to check. + + testptr(obj, TypeEntries::type_unknown); + jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. + + cmpptr(mdo_addr, 0); + jccb(Assembler::equal, none); + cmpptr(mdo_addr, TypeEntries::null_seen); + jccb(Assembler::equal, none); + // There is a chance that the checks above (re-reading profiling + // data from memory) fail if another thread has just set the + // profiling to this obj's klass + xorptr(obj, mdo_addr); + testptr(obj, TypeEntries::type_klass_mask); + jccb(Assembler::zero, next); + + // different than before. Cannot keep accurate profile. + orptr(mdo_addr, TypeEntries::type_unknown); + jmpb(next); + + bind(none); + // first time here. Set profile type. + movptr(mdo_addr, obj); + + bind(next); +} + +void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) { + if (!ProfileInterpreter) { + return; + } + + if (MethodData::profile_arguments()) { + Label profile_continue; + + test_method_data_pointer(mdp, profile_continue); + + int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); + + cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); + jcc(Assembler::notEqual, profile_continue); + + Label done; + int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset()); + addptr(mdp, off_to_args); + + for (int i = 0; i < TypeProfileArgsLimit; i++) { + if (i > 0) { + movl(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args)); + subl(tmp, i*TypeStackSlotEntries::per_arg_count()); + cmpl(tmp, TypeStackSlotEntries::per_arg_count()); + jcc(Assembler::less, done); + } + movptr(tmp, Address(callee, Method::const_offset())); + load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); + subl(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args)); + subl(tmp, 1); + Address arg_addr = argument_address(tmp); + movptr(tmp, arg_addr); + + Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args); + profile_obj_type(tmp, mdo_arg_addr); + + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); + addptr(mdp, to_add); + off_to_args += to_add; + } + + bind(done); + + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); + + bind(profile_continue); + } +} void InterpreterMacroAssembler::profile_call(Register mdp) { if (ProfileInterpreter) { diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp index 49a41f61d54..6ccac4a126e 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp @@ -215,6 +215,8 @@ class InterpreterMacroAssembler: public MacroAssembler { void profile_taken_branch(Register mdp, Register bumped_count); void profile_not_taken_branch(Register mdp); + void profile_obj_type(Register obj, const Address& mdo_addr); + void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual); void profile_call(Register mdp); void profile_final_call(Register mdp); void profile_virtual_call(Register receiver, Register mdp, Register scratch2, diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp index 88d57d046a5..28c7c8b383f 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp @@ -1067,6 +1067,102 @@ void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) { } } +void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) { + Label update, next, none; + + verify_oop(obj); + + testptr(obj, obj); + jccb(Assembler::notZero, update); + orptr(mdo_addr, TypeEntries::null_seen); + jmpb(next); + + bind(update); + load_klass(obj, obj); + + xorptr(obj, mdo_addr); + testptr(obj, TypeEntries::type_klass_mask); + jccb(Assembler::zero, next); // klass seen before, nothing to + // do. The unknown bit may have been + // set already but no need to check. + + testptr(obj, TypeEntries::type_unknown); + jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. + + // There is a chance that by the time we do these checks (re-reading + // profiling data from memory) another thread has set the profling + // to this obj's klass and we set the profiling as unknow + // erroneously + cmpptr(mdo_addr, 0); + jccb(Assembler::equal, none); + cmpptr(mdo_addr, TypeEntries::null_seen); + jccb(Assembler::equal, none); + // There is a chance that the checks above (re-reading profiling + // data from memory) fail if another thread has just set the + // profiling to this obj's klass + xorptr(obj, mdo_addr); + testptr(obj, TypeEntries::type_klass_mask); + jccb(Assembler::zero, next); + + // different than before. Cannot keep accurate profile. + orptr(mdo_addr, TypeEntries::type_unknown); + jmpb(next); + + bind(none); + // first time here. Set profile type. + movptr(mdo_addr, obj); + + bind(next); +} + +void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) { + if (!ProfileInterpreter) { + return; + } + + if (MethodData::profile_arguments()) { + Label profile_continue; + + test_method_data_pointer(mdp, profile_continue); + + int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); + + cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); + jcc(Assembler::notEqual, profile_continue); + + Label done; + int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset()); + addptr(mdp, off_to_args); + + for (int i = 0; i < TypeProfileArgsLimit; i++) { + if (i > 0) { + movq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args)); + subl(tmp, i*TypeStackSlotEntries::per_arg_count()); + cmpl(tmp, TypeStackSlotEntries::per_arg_count()); + jcc(Assembler::less, done); + } + movptr(tmp, Address(callee, Method::const_offset())); + load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); + subq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args)); + subl(tmp, 1); + Address arg_addr = argument_address(tmp); + movptr(tmp, arg_addr); + + Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args); + profile_obj_type(tmp, mdo_arg_addr); + + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); + addptr(mdp, to_add); + off_to_args += to_add; + } + + bind(done); + + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); + + bind(profile_continue); + } +} void InterpreterMacroAssembler::profile_call(Register mdp) { if (ProfileInterpreter) { diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp index 8bfc44fe4bc..2e1ea945c1d 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp @@ -224,6 +224,8 @@ class InterpreterMacroAssembler: public MacroAssembler { void profile_taken_branch(Register mdp, Register bumped_count); void profile_not_taken_branch(Register mdp); + void profile_obj_type(Register obj, const Address& mdo_addr); + void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual); void profile_call(Register mdp); void profile_final_call(Register mdp); void profile_virtual_call(Register receiver, Register mdp, diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index 293b3b73a37..198fc98e86a 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -773,6 +773,7 @@ class MacroAssembler: public Assembler { void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + void orptr(Address dst, int32_t imm32) { LP64_ONLY(orq(dst, imm32)) NOT_LP64(orl(dst, imm32)); } void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); } void testptr(Register src1, Register src2); diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp index 6c6cc4f9474..6e6033b02b6 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -2970,6 +2970,7 @@ void TemplateTable::invokevirtual_helper(Register index, // profile this call __ profile_final_call(rax); + __ profile_arguments_type(rax, method, rsi, true); __ jump_from_interpreted(method, rax); @@ -2984,6 +2985,7 @@ void TemplateTable::invokevirtual_helper(Register index, // get target Method* & entry point __ lookup_virtual_method(rax, index, method); + __ profile_arguments_type(rdx, method, rsi, true); __ jump_from_interpreted(method, rdx); } @@ -3013,6 +3015,7 @@ void TemplateTable::invokespecial(int byte_no) { __ null_check(rcx); // do the call __ profile_call(rax); + __ profile_arguments_type(rax, rbx, rsi, false); __ jump_from_interpreted(rbx, rax); } @@ -3023,6 +3026,7 @@ void TemplateTable::invokestatic(int byte_no) { prepare_invoke(byte_no, rbx); // get f1 Method* // do the call __ profile_call(rax); + __ profile_arguments_type(rax, rbx, rsi, false); __ jump_from_interpreted(rbx, rax); } @@ -3082,6 +3086,8 @@ void TemplateTable::invokeinterface(int byte_no) { __ testptr(rbx, rbx); __ jcc(Assembler::zero, no_such_method); + __ profile_arguments_type(rdx, rbx, rsi, true); + // do the call // rcx: receiver // rbx,: Method* @@ -3138,6 +3144,7 @@ void TemplateTable::invokehandle(int byte_no) { // FIXME: profile the LambdaForm also __ profile_final_call(rax); + __ profile_arguments_type(rdx, rbx_method, rsi, true); __ jump_from_interpreted(rbx_method, rdx); } @@ -3171,6 +3178,7 @@ void TemplateTable::invokedynamic(int byte_no) { // %%% should make a type profile for any invokedynamic that takes a ref argument // profile this call __ profile_call(rsi); + __ profile_arguments_type(rdx, rbx, rsi, false); __ verify_oop(rax_callsite); diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp index e97c5386c7a..8c49726e5ff 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -3026,6 +3026,7 @@ void TemplateTable::invokevirtual_helper(Register index, // profile this call __ profile_final_call(rax); + __ profile_arguments_type(rax, method, r13, true); __ jump_from_interpreted(method, rax); @@ -3040,6 +3041,7 @@ void TemplateTable::invokevirtual_helper(Register index, // get target Method* & entry point __ lookup_virtual_method(rax, index, method); + __ profile_arguments_type(rdx, method, r13, true); __ jump_from_interpreted(method, rdx); } @@ -3069,6 +3071,7 @@ void TemplateTable::invokespecial(int byte_no) { __ null_check(rcx); // do the call __ profile_call(rax); + __ profile_arguments_type(rax, rbx, r13, false); __ jump_from_interpreted(rbx, rax); } @@ -3079,6 +3082,7 @@ void TemplateTable::invokestatic(int byte_no) { prepare_invoke(byte_no, rbx); // get f1 Method* // do the call __ profile_call(rax); + __ profile_arguments_type(rax, rbx, r13, false); __ jump_from_interpreted(rbx, rax); } @@ -3136,6 +3140,8 @@ void TemplateTable::invokeinterface(int byte_no) { __ testptr(rbx, rbx); __ jcc(Assembler::zero, no_such_method); + __ profile_arguments_type(rdx, rbx, r13, true); + // do the call // rcx: receiver // rbx,: Method* @@ -3193,6 +3199,7 @@ void TemplateTable::invokehandle(int byte_no) { // FIXME: profile the LambdaForm also __ profile_final_call(rax); + __ profile_arguments_type(rdx, rbx_method, r13, true); __ jump_from_interpreted(rbx_method, rdx); } @@ -3226,6 +3233,7 @@ void TemplateTable::invokedynamic(int byte_no) { // %%% should make a type profile for any invokedynamic that takes a ref argument // profile this call __ profile_call(r13); + __ profile_arguments_type(rdx, rbx_method, r13, false); __ verify_oop(rax_callsite); diff --git a/hotspot/src/share/vm/c1/c1_Compilation.cpp b/hotspot/src/share/vm/c1/c1_Compilation.cpp index 1cdcab542fa..574fda19401 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.cpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp @@ -601,6 +601,17 @@ void Compilation::bailout(const char* msg) { } } +ciKlass* Compilation::cha_exact_type(ciType* type) { + if (type != NULL && type->is_loaded() && type->is_instance_klass()) { + ciInstanceKlass* ik = type->as_instance_klass(); + assert(ik->exact_klass() == NULL, "no cha for final klass"); + if (DeoptC1 && UseCHA && !(ik->has_subklass() || ik->is_interface())) { + dependency_recorder()->assert_leaf_type(ik); + return ik; + } + } + return NULL; +} void Compilation::print_timers() { // tty->print_cr(" Native methods : %6.3f s, Average : %2.3f", CompileBroker::_t_native_compilation.seconds(), CompileBroker::_t_native_compilation.seconds() / CompileBroker::_total_native_compile_count); diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp index f98ae97f309..7386dc414c8 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.hpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp @@ -246,6 +246,8 @@ class Compilation: public StackObj { (RangeCheckElimination || UseLoopInvariantCodeMotion) && method()->method_data()->trap_count(Deoptimization::Reason_none) == 0; } + + ciKlass* cha_exact_type(ciType* type); }; diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index 03d0d75fa30..f93a6e89050 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -1658,6 +1658,42 @@ Dependencies* GraphBuilder::dependency_recorder() const { return compilation()->dependency_recorder(); } +// How many arguments do we want to profile? +Values* GraphBuilder::args_list_for_profiling(int& start, bool may_have_receiver) { + int n = 0; + assert(start == 0, "should be initialized"); + if (MethodData::profile_arguments()) { + ciProfileData* data = method()->method_data()->bci_to_data(bci()); + if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { + n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments(); + bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci())); + start = has_receiver ? 1 : 0; + } + } + if (n > 0) { + return new Values(n); + } + return NULL; +} + +// Collect arguments that we want to profile in a list +Values* GraphBuilder::collect_args_for_profiling(Values* args, bool may_have_receiver) { + int start = 0; + Values* obj_args = args_list_for_profiling(start, may_have_receiver); + if (obj_args == NULL) { + return NULL; + } + int s = obj_args->size(); + for (int i = start, j = 0; j < s; i++) { + if (args->at(i)->type()->is_object_kind()) { + obj_args->push(args->at(i)); + j++; + } + } + assert(s == obj_args->length(), "missed on arg?"); + return obj_args; +} + void GraphBuilder::invoke(Bytecodes::Code code) { bool will_link; @@ -1957,7 +1993,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) { } else if (exact_target != NULL) { target_klass = exact_target->holder(); } - profile_call(target, recv, target_klass); + profile_call(target, recv, target_klass, collect_args_for_profiling(args, false), false); } } @@ -3509,7 +3545,7 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { recv = args->at(0); null_check(recv); } - profile_call(callee, recv, NULL); + profile_call(callee, recv, NULL, collect_args_for_profiling(args, true), true); } } } @@ -3763,7 +3799,28 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode compilation()->set_would_profile(true); if (profile_calls()) { - profile_call(callee, recv, holder_known ? callee->holder() : NULL); + int start = 0; + Values* obj_args = args_list_for_profiling(start, has_receiver); + if (obj_args != NULL) { + int s = obj_args->size(); + // if called through method handle invoke, some arguments may have been popped + for (int i = args_base+start, j = 0; j < obj_args->size() && i < state()->stack_size(); ) { + Value v = state()->stack_at_inc(i); + if (v->type()->is_object_kind()) { + obj_args->push(v); + j++; + } + } +#ifdef ASSERT + { + bool ignored_will_link; + ciSignature* declared_signature = NULL; + ciMethod* real_target = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature); + assert(s == obj_args->length() || real_target->is_method_handle_intrinsic(), "missed on arg?"); + } +#endif + } + profile_call(callee, recv, holder_known ? callee->holder() : NULL, obj_args, true); } } @@ -4251,8 +4308,8 @@ void GraphBuilder::print_stats() { } #endif // PRODUCT -void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder) { - append(new ProfileCall(method(), bci(), callee, recv, known_holder)); +void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { + append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); } void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp index ae5afd4e04d..217da78bb26 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp @@ -374,7 +374,7 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { void print_inlining(ciMethod* callee, const char* msg = NULL, bool success = true); - void profile_call(ciMethod* callee, Value recv, ciKlass* predicted_holder); + void profile_call(ciMethod* callee, Value recv, ciKlass* predicted_holder, Values* obj_args, bool inlined); void profile_invocation(ciMethod* inlinee, ValueStack* state); // Shortcuts to profiling control. @@ -386,6 +386,9 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { bool profile_inlined_calls() { return _compilation->profile_inlined_calls(); } bool profile_checkcasts() { return _compilation->profile_checkcasts(); } + Values* args_list_for_profiling(int& start, bool may_have_receiver); + Values* collect_args_for_profiling(Values* args, bool may_have_receiver); + public: NOT_PRODUCT(void print_stats();) diff --git a/hotspot/src/share/vm/c1/c1_Instruction.cpp b/hotspot/src/share/vm/c1/c1_Instruction.cpp index a026b4cbea0..e5829611e66 100644 --- a/hotspot/src/share/vm/c1/c1_Instruction.cpp +++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp @@ -104,6 +104,14 @@ void Instruction::state_values_do(ValueVisitor* f) { } } +ciType* Instruction::exact_type() const { + ciType* t = declared_type(); + if (t != NULL && t->is_klass()) { + return t->as_klass()->exact_klass(); + } + return NULL; +} + #ifndef PRODUCT void Instruction::check_state(ValueStack* state) { @@ -135,9 +143,7 @@ void Instruction::print(InstructionPrinter& ip) { // perform constant and interval tests on index value bool AccessIndexed::compute_needs_range_check() { - if (length()) { - Constant* clength = length()->as_Constant(); Constant* cindex = index()->as_Constant(); if (clength && cindex) { @@ -157,34 +163,8 @@ bool AccessIndexed::compute_needs_range_check() { } -ciType* Local::exact_type() const { - ciType* type = declared_type(); - - // for primitive arrays, the declared type is the exact type - if (type->is_type_array_klass()) { - return type; - } else if (type->is_instance_klass()) { - ciInstanceKlass* ik = (ciInstanceKlass*)type; - if (ik->is_loaded() && ik->is_final() && !ik->is_interface()) { - return type; - } - } else if (type->is_obj_array_klass()) { - ciObjArrayKlass* oak = (ciObjArrayKlass*)type; - ciType* base = oak->base_element_type(); - if (base->is_instance_klass()) { - ciInstanceKlass* ik = base->as_instance_klass(); - if (ik->is_loaded() && ik->is_final()) { - return type; - } - } else if (base->is_primitive_type()) { - return type; - } - } - return NULL; -} - ciType* Constant::exact_type() const { - if (type()->is_object()) { + if (type()->is_object() && type()->as_ObjectType()->is_loaded()) { return type()->as_ObjectType()->exact_type(); } return NULL; @@ -192,19 +172,18 @@ ciType* Constant::exact_type() const { ciType* LoadIndexed::exact_type() const { ciType* array_type = array()->exact_type(); - if (array_type == NULL) { - return NULL; - } - assert(array_type->is_array_klass(), "what else?"); - ciArrayKlass* ak = (ciArrayKlass*)array_type; + if (array_type != NULL) { + assert(array_type->is_array_klass(), "what else?"); + ciArrayKlass* ak = (ciArrayKlass*)array_type; - if (ak->element_type()->is_instance_klass()) { - ciInstanceKlass* ik = (ciInstanceKlass*)ak->element_type(); - if (ik->is_loaded() && ik->is_final()) { - return ik; + if (ak->element_type()->is_instance_klass()) { + ciInstanceKlass* ik = (ciInstanceKlass*)ak->element_type(); + if (ik->is_loaded() && ik->is_final()) { + return ik; + } } } - return NULL; + return Instruction::exact_type(); } @@ -224,22 +203,6 @@ ciType* LoadField::declared_type() const { } -ciType* LoadField::exact_type() const { - ciType* type = declared_type(); - // for primitive arrays, the declared type is the exact type - if (type->is_type_array_klass()) { - return type; - } - if (type->is_instance_klass()) { - ciInstanceKlass* ik = (ciInstanceKlass*)type; - if (ik->is_loaded() && ik->is_final()) { - return type; - } - } - return NULL; -} - - ciType* NewTypeArray::exact_type() const { return ciTypeArrayKlass::make(elt_type()); } @@ -264,16 +227,6 @@ ciType* CheckCast::declared_type() const { return klass(); } -ciType* CheckCast::exact_type() const { - if (klass()->is_instance_klass()) { - ciInstanceKlass* ik = (ciInstanceKlass*)klass(); - if (ik->is_loaded() && ik->is_final()) { - return ik; - } - } - return NULL; -} - // Implementation of ArithmeticOp bool ArithmeticOp::is_commutative() const { diff --git a/hotspot/src/share/vm/c1/c1_Instruction.hpp b/hotspot/src/share/vm/c1/c1_Instruction.hpp index 9563b720a10..466d814c674 100644 --- a/hotspot/src/share/vm/c1/c1_Instruction.hpp +++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp @@ -322,6 +322,36 @@ class Instruction: public CompilationResourceObj { _type = type; } + // Helper class to keep track of which arguments need a null check + class ArgsNonNullState { + private: + int _nonnull_state; // mask identifying which args are nonnull + public: + ArgsNonNullState() + : _nonnull_state(AllBits) {} + + // Does argument number i needs a null check? + bool arg_needs_null_check(int i) const { + // No data is kept for arguments starting at position 33 so + // conservatively assume that they need a null check. + if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { + return is_set_nth_bit(_nonnull_state, i); + } + return true; + } + + // Set whether argument number i needs a null check or not + void set_arg_needs_null_check(int i, bool check) { + if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { + if (check) { + _nonnull_state |= nth_bit(i); + } else { + _nonnull_state &= ~(nth_bit(i)); + } + } + } + }; + public: void* operator new(size_t size) throw() { Compilation* c = Compilation::current(); @@ -566,7 +596,7 @@ class Instruction: public CompilationResourceObj { virtual void other_values_do(ValueVisitor* f) { /* usually no other - override on demand */ } void values_do(ValueVisitor* f) { input_values_do(f); state_values_do(f); other_values_do(f); } - virtual ciType* exact_type() const { return NULL; } + virtual ciType* exact_type() const; virtual ciType* declared_type() const { return NULL; } // hashing @@ -689,7 +719,6 @@ LEAF(Local, Instruction) int java_index() const { return _java_index; } virtual ciType* declared_type() const { return _declared_type; } - virtual ciType* exact_type() const; // generic virtual void input_values_do(ValueVisitor* f) { /* no values */ } @@ -806,7 +835,6 @@ LEAF(LoadField, AccessField) {} ciType* declared_type() const; - ciType* exact_type() const; // generic HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if needs patching or if volatile @@ -1299,6 +1327,7 @@ BASE(NewArray, StateSplit) virtual bool needs_exception_state() const { return false; } + ciType* exact_type() const { return NULL; } ciType* declared_type() const; // generic @@ -1422,7 +1451,6 @@ LEAF(CheckCast, TypeCheck) } ciType* declared_type() const; - ciType* exact_type() const; }; @@ -1490,7 +1518,7 @@ LEAF(Intrinsic, StateSplit) vmIntrinsics::ID _id; Values* _args; Value _recv; - int _nonnull_state; // mask identifying which args are nonnull + ArgsNonNullState _nonnull_state; public: // preserves_state can be set to true for Intrinsics @@ -1511,7 +1539,6 @@ LEAF(Intrinsic, StateSplit) , _id(id) , _args(args) , _recv(NULL) - , _nonnull_state(AllBits) { assert(args != NULL, "args must exist"); ASSERT_VALUES @@ -1537,21 +1564,12 @@ LEAF(Intrinsic, StateSplit) Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; } bool preserves_state() const { return check_flag(PreservesStateFlag); } - bool arg_needs_null_check(int i) { - if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { - return is_set_nth_bit(_nonnull_state, i); - } - return true; + bool arg_needs_null_check(int i) const { + return _nonnull_state.arg_needs_null_check(i); } void set_arg_needs_null_check(int i, bool check) { - if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { - if (check) { - _nonnull_state |= nth_bit(i); - } else { - _nonnull_state &= ~(nth_bit(i)); - } - } + _nonnull_state.set_arg_needs_null_check(i, check); } // generic @@ -2450,35 +2468,56 @@ LEAF(UnsafePrefetchWrite, UnsafePrefetch) LEAF(ProfileCall, Instruction) private: - ciMethod* _method; - int _bci_of_invoke; - ciMethod* _callee; // the method that is called at the given bci - Value _recv; - ciKlass* _known_holder; + ciMethod* _method; + int _bci_of_invoke; + ciMethod* _callee; // the method that is called at the given bci + Value _recv; + ciKlass* _known_holder; + Values* _obj_args; // arguments for type profiling + ArgsNonNullState _nonnull_state; // Do we know whether some arguments are never null? + bool _inlined; // Are we profiling a call that is inlined public: - ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder) + ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) : Instruction(voidType) , _method(method) , _bci_of_invoke(bci) , _callee(callee) , _recv(recv) , _known_holder(known_holder) + , _obj_args(obj_args) + , _inlined(inlined) { // The ProfileCall has side-effects and must occur precisely where located pin(); } - ciMethod* method() { return _method; } - int bci_of_invoke() { return _bci_of_invoke; } - ciMethod* callee() { return _callee; } - Value recv() { return _recv; } - ciKlass* known_holder() { return _known_holder; } + ciMethod* method() const { return _method; } + int bci_of_invoke() const { return _bci_of_invoke; } + ciMethod* callee() const { return _callee; } + Value recv() const { return _recv; } + ciKlass* known_holder() const { return _known_holder; } + int nb_profiled_args() const { return _obj_args == NULL ? 0 : _obj_args->length(); } + Value profiled_arg_at(int i) const { return _obj_args->at(i); } + bool arg_needs_null_check(int i) const { + return _nonnull_state.arg_needs_null_check(i); + } + bool inlined() const { return _inlined; } - virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); } + void set_arg_needs_null_check(int i, bool check) { + _nonnull_state.set_arg_needs_null_check(i, check); + } + + virtual void input_values_do(ValueVisitor* f) { + if (_recv != NULL) { + f->visit(&_recv); + } + for (int i = 0; i < nb_profiled_args(); i++) { + f->visit(_obj_args->adr_at(i)); + } + } }; - // Call some C runtime function that doesn't safepoint, // optionally passing the current thread as the first argument. LEAF(RuntimeCall, Instruction) diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp index cfca00ab277..c15538116fd 100644 --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp @@ -892,6 +892,14 @@ void InstructionPrinter::do_ProfileCall(ProfileCall* x) { if (x->known_holder() != NULL) { output()->print(", "); print_klass(x->known_holder()); + output()->print(" "); + } + for (int i = 0; i < x->nb_profiled_args(); i++) { + if (i > 0) output()->print(", "); + print_value(x->profiled_arg_at(i)); + if (x->arg_needs_null_check(i)) { + output()->print(" [NC]"); + } } output()->put(')'); } diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index cb0ceab90c0..f40d9133306 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -1001,6 +1001,17 @@ void LIR_OpVisitState::visit(LIR_Op* op) { assert(opProfileCall->_tmp1->is_valid(), "used"); do_temp(opProfileCall->_tmp1); break; } + +// LIR_OpProfileType: + case lir_profile_type: { + assert(op->as_OpProfileType() != NULL, "must be"); + LIR_OpProfileType* opProfileType = (LIR_OpProfileType*)op; + + do_input(opProfileType->_mdp); do_temp(opProfileType->_mdp); + do_input(opProfileType->_obj); + do_temp(opProfileType->_tmp); + break; + } default: ShouldNotReachHere(); } @@ -1151,6 +1162,10 @@ void LIR_OpProfileCall::emit_code(LIR_Assembler* masm) { masm->emit_profile_call(this); } +void LIR_OpProfileType::emit_code(LIR_Assembler* masm) { + masm->emit_profile_type(this); +} + // LIR_List LIR_List::LIR_List(Compilation* compilation, BlockBegin* block) : _operations(8) @@ -1803,6 +1818,8 @@ const char * LIR_Op::name() const { case lir_cas_int: s = "cas_int"; break; // LIR_OpProfileCall case lir_profile_call: s = "profile_call"; break; + // LIR_OpProfileType + case lir_profile_type: s = "profile_type"; break; // LIR_OpAssert #ifdef ASSERT case lir_assert: s = "assert"; break; @@ -2086,6 +2103,15 @@ void LIR_OpProfileCall::print_instr(outputStream* out) const { tmp1()->print(out); out->print(" "); } +// LIR_OpProfileType +void LIR_OpProfileType::print_instr(outputStream* out) const { + out->print("exact = "); exact_klass()->print_name_on(out); + out->print("current = "); ciTypeEntries::print_ciklass(out, current_klass()); + mdp()->print(out); out->print(" "); + obj()->print(out); out->print(" "); + tmp()->print(out); out->print(" "); +} + #endif // PRODUCT // Implementation of LIR_InsertionBuffer diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index d0dca72f386..a339af5098f 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -882,6 +882,7 @@ class LIR_OpLock; class LIR_OpTypeCheck; class LIR_OpCompareAndSwap; class LIR_OpProfileCall; +class LIR_OpProfileType; #ifdef ASSERT class LIR_OpAssert; #endif @@ -1005,6 +1006,7 @@ enum LIR_Code { , end_opCompareAndSwap , begin_opMDOProfile , lir_profile_call + , lir_profile_type , end_opMDOProfile , begin_opAssert , lir_assert @@ -1145,6 +1147,7 @@ class LIR_Op: public CompilationResourceObj { virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; } virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; } virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; } + virtual LIR_OpProfileType* as_OpProfileType() { return NULL; } #ifdef ASSERT virtual LIR_OpAssert* as_OpAssert() { return NULL; } #endif @@ -1925,8 +1928,8 @@ class LIR_OpProfileCall : public LIR_Op { public: // Destroys recv - LIR_OpProfileCall(LIR_Code code, ciMethod* profiled_method, int profiled_bci, ciMethod* profiled_callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* known_holder) - : LIR_Op(code, LIR_OprFact::illegalOpr, NULL) // no result, no info + LIR_OpProfileCall(ciMethod* profiled_method, int profiled_bci, ciMethod* profiled_callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* known_holder) + : LIR_Op(lir_profile_call, LIR_OprFact::illegalOpr, NULL) // no result, no info , _profiled_method(profiled_method) , _profiled_bci(profiled_bci) , _profiled_callee(profiled_callee) @@ -1948,6 +1951,45 @@ class LIR_OpProfileCall : public LIR_Op { virtual void print_instr(outputStream* out) const PRODUCT_RETURN; }; +// LIR_OpProfileType +class LIR_OpProfileType : public LIR_Op { + friend class LIR_OpVisitState; + + private: + LIR_Opr _mdp; + LIR_Opr _obj; + LIR_Opr _tmp; + ciKlass* _exact_klass; // non NULL if we know the klass statically (no need to load it from _obj) + intptr_t _current_klass; // what the profiling currently reports + bool _not_null; // true if we know statically that _obj cannot be null + bool _no_conflict; // true if we're profling parameters, _exact_klass is not NULL and we know + // _exact_klass it the only possible type for this parameter in any context. + + public: + // Destroys recv + LIR_OpProfileType(LIR_Opr mdp, LIR_Opr obj, ciKlass* exact_klass, intptr_t current_klass, LIR_Opr tmp, bool not_null, bool no_conflict) + : LIR_Op(lir_profile_type, LIR_OprFact::illegalOpr, NULL) // no result, no info + , _mdp(mdp) + , _obj(obj) + , _exact_klass(exact_klass) + , _current_klass(current_klass) + , _tmp(tmp) + , _not_null(not_null) + , _no_conflict(no_conflict) { } + + LIR_Opr mdp() const { return _mdp; } + LIR_Opr obj() const { return _obj; } + LIR_Opr tmp() const { return _tmp; } + ciKlass* exact_klass() const { return _exact_klass; } + intptr_t current_klass() const { return _current_klass; } + bool not_null() const { return _not_null; } + bool no_conflict() const { return _no_conflict; } + + virtual void emit_code(LIR_Assembler* masm); + virtual LIR_OpProfileType* as_OpProfileType() { return this; } + virtual void print_instr(outputStream* out) const PRODUCT_RETURN; +}; + class LIR_InsertionBuffer; //--------------------------------LIR_List--------------------------------------------------- @@ -2247,7 +2289,10 @@ class LIR_List: public CompilationResourceObj { ciMethod* profiled_method, int profiled_bci); // MethodData* profiling void profile_call(ciMethod* method, int bci, ciMethod* callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* cha_klass) { - append(new LIR_OpProfileCall(lir_profile_call, method, bci, callee, mdo, recv, t1, cha_klass)); + append(new LIR_OpProfileCall(method, bci, callee, mdo, recv, t1, cha_klass)); + } + void profile_type(LIR_Address* mdp, LIR_Opr obj, ciKlass* exact_klass, intptr_t current_klass, LIR_Opr tmp, bool not_null, bool no_conflict) { + append(new LIR_OpProfileType(LIR_OprFact::address(mdp), obj, exact_klass, current_klass, tmp, not_null, no_conflict)); } void xadd(LIR_Opr src, LIR_Opr add, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xadd, src, add, res, tmp)); } diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 57df2725ee2..68f249a2aed 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -208,6 +208,7 @@ class LIR_Assembler: public CompilationResourceObj { void emit_call(LIR_OpJavaCall* op); void emit_rtcall(LIR_OpRTCall* op); void emit_profile_call(LIR_OpProfileCall* op); + void emit_profile_type(LIR_OpProfileType* op); void emit_delay(LIR_OpDelay* op); void arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index f71470e5ee0..3eedf1f313a 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2571,6 +2571,78 @@ void LIRGenerator::do_Goto(Goto* x) { } +ciKlass* LIRGenerator::profile_arg_type(ciMethodData* md, int md_base_offset, int md_offset, intptr_t profiled_k, Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_k) { + ciKlass* result = NULL; + bool do_null = !not_null && !TypeEntries::was_null_seen(profiled_k); + bool do_update = !TypeEntries::is_type_unknown(profiled_k); + // known not to be null or null bit already set and already set to + // unknown: nothing we can do to improve profiling + if (!do_null && !do_update) { + return result; + } + + ciKlass* exact_klass = NULL; + Compilation* comp = Compilation::current(); + if (do_update) { + // try to find exact type, using CHA if possible, so that loading + // the klass from the object can be avoided + ciType* type = arg->exact_type(); + if (type == NULL) { + type = arg->declared_type(); + type = comp->cha_exact_type(type); + } + assert(type == NULL || type->is_klass(), "type should be class"); + exact_klass = (type != NULL && type->is_loaded()) ? (ciKlass*)type : NULL; + + do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass; + } + + if (!do_null && !do_update) { + return result; + } + + ciKlass* exact_signature_k = NULL; + if (do_update) { + // Is the type from the signature exact (the only one possible)? + exact_signature_k = signature_k->exact_klass(); + if (exact_signature_k == NULL) { + exact_signature_k = comp->cha_exact_type(signature_k); + } else { + result = exact_signature_k; + do_update = false; + // Known statically. No need to emit any code: prevent + // LIR_Assembler::emit_profile_type() from emitting useless code + profiled_k = ciTypeEntries::with_status(result, profiled_k); + } + if (exact_signature_k != NULL && exact_klass != exact_signature_k) { + assert(exact_klass == NULL, "arg and signature disagree?"); + // sometimes the type of the signature is better than the best type + // the compiler has + exact_klass = exact_signature_k; + do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass; + } + } + + if (!do_null && !do_update) { + return result; + } + + if (mdp == LIR_OprFact::illegalOpr) { + mdp = new_register(T_METADATA); + __ metadata2reg(md->constant_encoding(), mdp); + if (md_base_offset != 0) { + LIR_Address* base_type_address = new LIR_Address(mdp, md_base_offset, T_ADDRESS); + mdp = new_pointer_register(); + __ leal(LIR_OprFact::address(base_type_address), mdp); + } + } + LIRItem value(arg, this); + value.load_item(); + __ profile_type(new LIR_Address(mdp, md_offset, T_METADATA), + value.result(), exact_klass, profiled_k, new_pointer_register(), not_null, exact_signature_k != NULL); + return result; +} + void LIRGenerator::do_Base(Base* x) { __ std_entry(LIR_OprFact::illegalOpr); // Emit moves from physical registers / stack slots to virtual registers @@ -3004,12 +3076,52 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { } } +void LIRGenerator::profile_arguments(ProfileCall* x) { + if (MethodData::profile_arguments()) { + int bci = x->bci_of_invoke(); + ciMethodData* md = x->method()->method_data_or_null(); + ciProfileData* data = md->bci_to_data(bci); + if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { + ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset(); + int base_offset = md->byte_offset_of_slot(data, extra); + LIR_Opr mdp = LIR_OprFact::illegalOpr; + ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args(); + + Bytecodes::Code bc = x->method()->java_code_at_bci(bci); + int start = 0; + int stop = args->number_of_arguments(); + if (x->nb_profiled_args() < stop) { + // if called through method handle invoke, some arguments may have been popped + stop = x->nb_profiled_args(); + } + ciSignature* sig = x->callee()->signature(); + // method handle call to virtual method + bool has_receiver = x->inlined() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc); + ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL); + for (int i = 0; i < stop; i++) { + int off = in_bytes(TypeStackSlotEntries::type_offset(i)) - in_bytes(TypeStackSlotEntries::args_data_offset()); + ciKlass* exact = profile_arg_type(md, base_offset, off, + args->type(i), x->profiled_arg_at(i+start), mdp, + !x->arg_needs_null_check(i+start), sig_stream.next_klass()); + if (exact != NULL) { + md->set_argument_type(bci, i, exact); + } + } + } + } +} + void LIRGenerator::do_ProfileCall(ProfileCall* x) { // Need recv in a temporary register so it interferes with the other temporaries LIR_Opr recv = LIR_OprFact::illegalOpr; LIR_Opr mdo = new_register(T_OBJECT); // tmp is used to hold the counters on SPARC LIR_Opr tmp = new_pointer_register(); + + if (x->nb_profiled_args() > 0) { + profile_arguments(x); + } + if (x->recv() != NULL) { LIRItem value(x->recv(), this); value.load_item(); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp index 0a029207308..fce938a03d8 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp @@ -434,6 +434,8 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { void do_ThreadIDIntrinsic(Intrinsic* x); void do_ClassIDIntrinsic(Intrinsic* x); #endif + ciKlass* profile_arg_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k, Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_k); + void profile_arguments(ProfileCall* x); public: Compilation* compilation() const { return _compilation; } diff --git a/hotspot/src/share/vm/c1/c1_Optimizer.cpp b/hotspot/src/share/vm/c1/c1_Optimizer.cpp index 90dc2797210..0be6099aa61 100644 --- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp +++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp @@ -657,6 +657,7 @@ class NullCheckEliminator: public ValueVisitor { void handle_Intrinsic (Intrinsic* x); void handle_ExceptionObject (ExceptionObject* x); void handle_Phi (Phi* x); + void handle_ProfileCall (ProfileCall* x); }; @@ -715,7 +716,8 @@ void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {} void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} -void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); } +void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); + nce()->handle_ProfileCall(x); } void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {} void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {} void NullCheckVisitor::do_MemBar (MemBar* x) {} @@ -1134,6 +1136,11 @@ void NullCheckEliminator::handle_Phi(Phi* x) { } } +void NullCheckEliminator::handle_ProfileCall(ProfileCall* x) { + for (int i = 0; i < x->nb_profiled_args(); i++) { + x->set_arg_needs_null_check(i, !set_contains(x->profiled_arg_at(i))); + } +} void Optimizer::eliminate_null_checks() { ResourceMark rm; diff --git a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp index ae1a2556881..1d7897bda9a 100644 --- a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp +++ b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp @@ -162,7 +162,7 @@ public: void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }; void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }; void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }; - void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; + void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; void do_MemBar (MemBar* x) { /* nothing to do */ }; void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ }; diff --git a/hotspot/src/share/vm/ci/ciClassList.hpp b/hotspot/src/share/vm/ci/ciClassList.hpp index 71e5dd18c7f..c3131f5ee67 100644 --- a/hotspot/src/share/vm/ci/ciClassList.hpp +++ b/hotspot/src/share/vm/ci/ciClassList.hpp @@ -102,6 +102,7 @@ friend class ciMethodData; \ friend class ciMethodHandle; \ friend class ciMethodType; \ friend class ciReceiverTypeData; \ +friend class ciTypeEntries; \ friend class ciSymbol; \ friend class ciArray; \ friend class ciObjArray; \ diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp index 0b244a2972c..fdd93ddc58c 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp @@ -235,6 +235,13 @@ public: bool is_instance_klass() const { return true; } bool is_java_klass() const { return true; } + virtual ciKlass* exact_klass() { + if (is_loaded() && is_final() && !is_interface()) { + return this; + } + return NULL; + } + // Dump the current state of this klass for compilation replay. virtual void dump_replay_data(outputStream* out); }; diff --git a/hotspot/src/share/vm/ci/ciKlass.hpp b/hotspot/src/share/vm/ci/ciKlass.hpp index d378059fcbc..7e03c1ede61 100644 --- a/hotspot/src/share/vm/ci/ciKlass.hpp +++ b/hotspot/src/share/vm/ci/ciKlass.hpp @@ -41,6 +41,7 @@ class ciKlass : public ciType { friend class ciEnv; friend class ciField; friend class ciMethod; + friend class ciMethodData; friend class ciObjArrayKlass; private: @@ -121,6 +122,8 @@ public: // What kind of ciObject is this? bool is_klass() const { return true; } + virtual ciKlass* exact_klass() = 0; + void print_name_on(outputStream* st); }; diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index 268888bfd56..fb06759154a 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -125,7 +125,7 @@ void ciMethodData::load_data() { #endif } -void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) { +void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) { for (uint row = 0; row < row_limit(); row++) { Klass* k = data->as_ReceiverTypeData()->receiver(row); if (k != NULL) { @@ -136,6 +136,13 @@ void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) { } +void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) { + for (int i = 0; i < number_of_arguments(); i++) { + intptr_t k = entries->type(i); + TypeStackSlotEntries::set_type(i, translate_klass(k)); + } +} + // Get the data at an arbitrary (sort of) data index. ciProfileData* ciMethodData::data_at(int data_index) { if (out_of_bounds(data_index)) { @@ -166,6 +173,10 @@ ciProfileData* ciMethodData::data_at(int data_index) { return new ciMultiBranchData(data_layout); case DataLayout::arg_info_data_tag: return new ciArgInfoData(data_layout); + case DataLayout::call_type_data_tag: + return new ciCallTypeData(data_layout); + case DataLayout::virtual_call_type_data_tag: + return new ciVirtualCallTypeData(data_layout); }; } @@ -288,6 +299,20 @@ void ciMethodData::set_would_profile(bool p) { } } +void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) { + VM_ENTRY_MARK; + MethodData* mdo = get_MethodData(); + if (mdo != NULL) { + ProfileData* data = mdo->bci_to_data(bci); + if (data->is_CallTypeData()) { + data->as_CallTypeData()->set_argument_type(i, k->get_Klass()); + } else { + assert(data->is_VirtualCallTypeData(), "no arguments!"); + data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass()); + } + } +} + bool ciMethodData::has_escape_info() { return eflag_set(MethodData::estimated); } @@ -478,7 +503,36 @@ void ciMethodData::print_data_on(outputStream* st) { } } -void ciReceiverTypeData::print_receiver_data_on(outputStream* st) { +void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) { + if (TypeEntries::is_type_none(k)) { + st->print("none"); + } else if (TypeEntries::is_type_unknown(k)) { + st->print("unknown"); + } else { + valid_ciklass(k)->print_name_on(st); + } + if (TypeEntries::was_null_seen(k)) { + st->print(" (null seen)"); + } +} + +void ciTypeStackSlotEntries::print_data_on(outputStream* st) const { + _pd->tab(st, true); + st->print("argument types"); + for (int i = 0; i < number_of_arguments(); i++) { + _pd->tab(st); + st->print("%d: stack (%u) ", i, stack_slot(i)); + print_ciklass(st, type(i)); + st->cr(); + } +} + +void ciCallTypeData::print_data_on(outputStream* st) const { + print_shared(st, "ciCallTypeData"); + args()->print_data_on(st); +} + +void ciReceiverTypeData::print_receiver_data_on(outputStream* st) const { uint row; int entries = 0; for (row = 0; row < row_limit(); row++) { @@ -494,13 +548,19 @@ void ciReceiverTypeData::print_receiver_data_on(outputStream* st) { } } -void ciReceiverTypeData::print_data_on(outputStream* st) { +void ciReceiverTypeData::print_data_on(outputStream* st) const { print_shared(st, "ciReceiverTypeData"); print_receiver_data_on(st); } -void ciVirtualCallData::print_data_on(outputStream* st) { +void ciVirtualCallData::print_data_on(outputStream* st) const { print_shared(st, "ciVirtualCallData"); rtd_super()->print_receiver_data_on(st); } + +void ciVirtualCallTypeData::print_data_on(outputStream* st) const { + print_shared(st, "ciVirtualCallTypeData"); + rtd_super()->print_receiver_data_on(st); + args()->print_data_on(st); +} #endif diff --git a/hotspot/src/share/vm/ci/ciMethodData.hpp b/hotspot/src/share/vm/ci/ciMethodData.hpp index 913ae31847e..8de598117a6 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.hpp +++ b/hotspot/src/share/vm/ci/ciMethodData.hpp @@ -41,6 +41,8 @@ class ciBranchData; class ciArrayData; class ciMultiBranchData; class ciArgInfoData; +class ciCallTypeData; +class ciVirtualCallTypeData; typedef ProfileData ciProfileData; @@ -59,6 +61,68 @@ public: ciJumpData(DataLayout* layout) : JumpData(layout) {}; }; +class ciTypeEntries { +protected: + static intptr_t translate_klass(intptr_t k) { + Klass* v = TypeEntries::valid_klass(k); + if (v != NULL) { + ciKlass* klass = CURRENT_ENV->get_klass(v); + return with_status(klass, k); + } + return with_status(NULL, k); + } + +public: + static ciKlass* valid_ciklass(intptr_t k) { + if (!TypeEntries::is_type_none(k) && + !TypeEntries::is_type_unknown(k)) { + return (ciKlass*)TypeEntries::klass_part(k); + } else { + return NULL; + } + } + + static intptr_t with_status(ciKlass* k, intptr_t in) { + return TypeEntries::with_status((intptr_t)k, in); + } + +#ifndef PRODUCT + static void print_ciklass(outputStream* st, intptr_t k); +#endif +}; + +class ciTypeStackSlotEntries : public TypeStackSlotEntries, ciTypeEntries { +public: + void translate_type_data_from(const TypeStackSlotEntries* args); + + ciKlass* valid_type(int i) const { + return valid_ciklass(type(i)); + } + +#ifndef PRODUCT + void print_data_on(outputStream* st) const; +#endif +}; + +class ciCallTypeData : public CallTypeData { +public: + ciCallTypeData(DataLayout* layout) : CallTypeData(layout) {} + + ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)CallTypeData::args(); } + + virtual void translate_from(const ProfileData* data) { + args()->translate_type_data_from(data->as_CallTypeData()->args()); + } + + ciKlass* valid_argument_type(int i) const { + return args()->valid_type(i); + } + +#ifndef PRODUCT + void print_data_on(outputStream* st) const; +#endif +}; + class ciReceiverTypeData : public ReceiverTypeData { public: ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {}; @@ -69,7 +133,7 @@ public: (intptr_t) recv); } - ciKlass* receiver(uint row) { + ciKlass* receiver(uint row) const { assert((uint)row < row_limit(), "oob"); ciKlass* recv = (ciKlass*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count); assert(recv == NULL || recv->is_klass(), "wrong type"); @@ -77,19 +141,19 @@ public: } // Copy & translate from oop based ReceiverTypeData - virtual void translate_from(ProfileData* data) { + virtual void translate_from(const ProfileData* data) { translate_receiver_data_from(data); } - void translate_receiver_data_from(ProfileData* data); + void translate_receiver_data_from(const ProfileData* data); #ifndef PRODUCT - void print_data_on(outputStream* st); - void print_receiver_data_on(outputStream* st); + void print_data_on(outputStream* st) const; + void print_receiver_data_on(outputStream* st) const; #endif }; class ciVirtualCallData : public VirtualCallData { // Fake multiple inheritance... It's a ciReceiverTypeData also. - ciReceiverTypeData* rtd_super() { return (ciReceiverTypeData*) this; } + ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; } public: ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {}; @@ -103,11 +167,44 @@ public: } // Copy & translate from oop based VirtualCallData - virtual void translate_from(ProfileData* data) { + virtual void translate_from(const ProfileData* data) { rtd_super()->translate_receiver_data_from(data); } #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; +#endif +}; + +class ciVirtualCallTypeData : public VirtualCallTypeData { +private: + // Fake multiple inheritance... It's a ciReceiverTypeData also. + ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; } + +public: + ciVirtualCallTypeData(DataLayout* layout) : VirtualCallTypeData(layout) {} + + ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); } + + void set_receiver(uint row, ciKlass* recv) { + rtd_super()->set_receiver(row, recv); + } + + ciKlass* receiver(uint row) const { + return rtd_super()->receiver(row); + } + + // Copy & translate from oop based VirtualCallData + virtual void translate_from(const ProfileData* data) { + rtd_super()->translate_receiver_data_from(data); + args()->translate_type_data_from(data->as_VirtualCallTypeData()->args()); + } + + ciKlass* valid_argument_type(int i) const { + return args()->valid_type(i); + } + +#ifndef PRODUCT + void print_data_on(outputStream* st) const; #endif }; @@ -247,6 +344,9 @@ public: // Also set the numer of loops and blocks in the method. // Again, this is used to determine if a method is trivial. void set_compilation_stats(short loops, short blocks); + // If the compiler finds a profiled type that is known statically + // for sure, set it in the MethodData + void set_argument_type(int bci, int i, ciKlass* k); void load_data(); diff --git a/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp b/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp index 3ccb54eac9c..91f2ebc42a0 100644 --- a/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp +++ b/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp @@ -179,3 +179,16 @@ ciObjArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass) { ciObjArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass) { GUARDED_VM_ENTRY(return make_impl(element_klass);) } + +ciKlass* ciObjArrayKlass::exact_klass() { + ciType* base = base_element_type(); + if (base->is_instance_klass()) { + ciInstanceKlass* ik = base->as_instance_klass(); + if (ik->exact_klass() != NULL) { + return this; + } + } else if (base->is_primitive_type()) { + return this; + } + return NULL; +} diff --git a/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp b/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp index ffbf8502804..7a45e867438 100644 --- a/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp +++ b/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp @@ -73,6 +73,8 @@ public: bool is_obj_array_klass() const { return true; } static ciObjArrayKlass* make(ciKlass* element_klass); + + virtual ciKlass* exact_klass(); }; #endif // SHARE_VM_CI_CIOBJARRAYKLASS_HPP diff --git a/hotspot/src/share/vm/ci/ciStreams.hpp b/hotspot/src/share/vm/ci/ciStreams.hpp index db46a4a85d3..92a1a4adf88 100644 --- a/hotspot/src/share/vm/ci/ciStreams.hpp +++ b/hotspot/src/share/vm/ci/ciStreams.hpp @@ -277,11 +277,14 @@ public: class ciSignatureStream : public StackObj { private: ciSignature* _sig; - int _pos; + int _pos; + // holder is a method's holder + ciKlass* _holder; public: - ciSignatureStream(ciSignature* signature) { + ciSignatureStream(ciSignature* signature, ciKlass* holder = NULL) { _sig = signature; _pos = 0; + _holder = holder; } bool at_return_type() { return _pos == _sig->count(); } @@ -301,6 +304,23 @@ public: return _sig->type_at(_pos); } } + + // next klass in the signature + ciKlass* next_klass() { + ciKlass* sig_k; + if (_holder != NULL) { + sig_k = _holder; + _holder = NULL; + } else { + while (!type()->is_klass()) { + next(); + } + assert(!at_return_type(), "passed end of signature"); + sig_k = type()->as_klass(); + next(); + } + return sig_k; + } }; diff --git a/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp b/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp index 5a57f74c497..b88aecb9c6c 100644 --- a/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp +++ b/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp @@ -57,6 +57,10 @@ public: // Make an array klass corresponding to the specified primitive type. static ciTypeArrayKlass* make(BasicType type); + + virtual ciKlass* exact_klass() { + return this; + } }; #endif // SHARE_VM_CI_CITYPEARRAYKLASS_HPP diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index 89a4cd4aa6b..efb45934d7e 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -56,6 +56,11 @@ void DataLayout::initialize(u1 tag, u2 bci, int cell_count) { if (needs_array_len(tag)) { set_cell_at(ArrayData::array_len_off_set, cell_count - 1); // -1 for header. } + if (tag == call_type_data_tag) { + CallTypeData::initialize(this, cell_count); + } else if (tag == virtual_call_type_data_tag) { + VirtualCallTypeData::initialize(this, cell_count); + } } void DataLayout::clean_weak_klass_links(BoolObjectClosure* cl) { @@ -76,7 +81,7 @@ ProfileData::ProfileData() { } #ifndef PRODUCT -void ProfileData::print_shared(outputStream* st, const char* name) { +void ProfileData::print_shared(outputStream* st, const char* name) const { st->print("bci: %d", bci()); st->fill_to(tab_width_one); st->print("%s", name); @@ -91,8 +96,8 @@ void ProfileData::print_shared(outputStream* st, const char* name) { st->print("flags(%d) ", flags); } -void ProfileData::tab(outputStream* st) { - st->fill_to(tab_width_two); +void ProfileData::tab(outputStream* st, bool first) const { + st->fill_to(first ? tab_width_one : tab_width_two); } #endif // !PRODUCT @@ -104,7 +109,7 @@ void ProfileData::tab(outputStream* st) { #ifndef PRODUCT -void BitData::print_data_on(outputStream* st) { +void BitData::print_data_on(outputStream* st) const { print_shared(st, "BitData"); } #endif // !PRODUCT @@ -115,7 +120,7 @@ void BitData::print_data_on(outputStream* st) { // A CounterData corresponds to a simple counter. #ifndef PRODUCT -void CounterData::print_data_on(outputStream* st) { +void CounterData::print_data_on(outputStream* st) const { print_shared(st, "CounterData"); st->print_cr("count(%u)", count()); } @@ -145,12 +150,130 @@ void JumpData::post_initialize(BytecodeStream* stream, MethodData* mdo) { } #ifndef PRODUCT -void JumpData::print_data_on(outputStream* st) { +void JumpData::print_data_on(outputStream* st) const { print_shared(st, "JumpData"); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); } #endif // !PRODUCT +int TypeStackSlotEntries::compute_cell_count(BytecodeStream* stream) { + int max = TypeProfileArgsLimit; + assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); + Bytecode_invoke inv(stream->method(), stream->bci()); + + ResourceMark rm; + SignatureStream ss(inv.signature()); + int args_count = MIN2(ss.reference_parameter_count(), max); + + return args_count * per_arg_cell_count + (args_count > 0 ? header_cell_count() : 0); +} + +class ArgumentOffsetComputer : public SignatureInfo { +private: + int _max; + GrowableArray _offsets; + + void set(int size, BasicType type) { _size += size; } + void do_object(int begin, int end) { + if (_offsets.length() < _max) { + _offsets.push(_size); + } + SignatureInfo::do_object(begin, end); + } + void do_array (int begin, int end) { + if (_offsets.length() < _max) { + _offsets.push(_size); + } + SignatureInfo::do_array(begin, end); + } + +public: + ArgumentOffsetComputer(Symbol* signature, int max) + : SignatureInfo(signature), _max(max), _offsets(Thread::current(), max) { + } + + int total() { lazy_iterate_parameters(); return _size; } + + int off_at(int i) const { return _offsets.at(i); } +}; + +void TypeStackSlotEntries::post_initialize(BytecodeStream* stream) { + ResourceMark rm; + + assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); + Bytecode_invoke inv(stream->method(), stream->bci()); + +#ifdef ASSERT + SignatureStream ss(inv.signature()); + int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); + assert(count > 0, "room for args type but none found?"); + check_number_of_arguments(count); +#endif + + int start = 0; + ArgumentOffsetComputer aos(inv.signature(), number_of_arguments()-start); + aos.total(); + bool has_receiver = inv.has_receiver(); + for (int i = start; i < number_of_arguments(); i++) { + set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); + set_type(i, type_none()); + } +} + +bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) { + return !is_type_none(p) && + !((Klass*)klass_part(p))->is_loader_alive(is_alive_cl); +} + +void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { + for (int i = 0; i < number_of_arguments(); i++) { + intptr_t p = type(i); + if (is_loader_alive(is_alive_cl, p)) { + set_type(i, type_none()); + } + } +} + +bool TypeStackSlotEntries::arguments_profiling_enabled() { + return MethodData::profile_arguments(); +} + +#ifndef PRODUCT +void TypeEntries::print_klass(outputStream* st, intptr_t k) { + if (is_type_none(k)) { + st->print("none"); + } else if (is_type_unknown(k)) { + st->print("unknown"); + } else { + valid_klass(k)->print_value_on(st); + } + if (was_null_seen(k)) { + st->print(" (null seen)"); + } +} + +void TypeStackSlotEntries::print_data_on(outputStream* st) const { + _pd->tab(st, true); + st->print("argument types"); + for (int i = 0; i < number_of_arguments(); i++) { + _pd->tab(st); + st->print("%d: stack(%u) ", i, stack_slot(i)); + print_klass(st, type(i)); + st->cr(); + } +} + +void CallTypeData::print_data_on(outputStream* st) const { + CounterData::print_data_on(st); + _args.print_data_on(st); +} + +void VirtualCallTypeData::print_data_on(outputStream* st) const { + VirtualCallData::print_data_on(st); + _args.print_data_on(st); +} +#endif + // ================================================================== // ReceiverTypeData // @@ -169,7 +292,7 @@ void ReceiverTypeData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { } #ifndef PRODUCT -void ReceiverTypeData::print_receiver_data_on(outputStream* st) { +void ReceiverTypeData::print_receiver_data_on(outputStream* st) const { uint row; int entries = 0; for (row = 0; row < row_limit(); row++) { @@ -190,11 +313,11 @@ void ReceiverTypeData::print_receiver_data_on(outputStream* st) { } } } -void ReceiverTypeData::print_data_on(outputStream* st) { +void ReceiverTypeData::print_data_on(outputStream* st) const { print_shared(st, "ReceiverTypeData"); print_receiver_data_on(st); } -void VirtualCallData::print_data_on(outputStream* st) { +void VirtualCallData::print_data_on(outputStream* st) const { print_shared(st, "VirtualCallData"); print_receiver_data_on(st); } @@ -246,7 +369,7 @@ address RetData::fixup_ret(int return_bci, MethodData* h_mdo) { #ifndef PRODUCT -void RetData::print_data_on(outputStream* st) { +void RetData::print_data_on(outputStream* st) const { print_shared(st, "RetData"); uint row; int entries = 0; @@ -281,7 +404,7 @@ void BranchData::post_initialize(BytecodeStream* stream, MethodData* mdo) { } #ifndef PRODUCT -void BranchData::print_data_on(outputStream* st) { +void BranchData::print_data_on(outputStream* st) const { print_shared(st, "BranchData"); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); @@ -355,7 +478,7 @@ void MultiBranchData::post_initialize(BytecodeStream* stream, } #ifndef PRODUCT -void MultiBranchData::print_data_on(outputStream* st) { +void MultiBranchData::print_data_on(outputStream* st) const { print_shared(st, "MultiBranchData"); st->print_cr("default_count(%u) displacement(%d)", default_count(), default_displacement()); @@ -369,7 +492,7 @@ void MultiBranchData::print_data_on(outputStream* st) { #endif #ifndef PRODUCT -void ArgInfoData::print_data_on(outputStream* st) { +void ArgInfoData::print_data_on(outputStream* st) const { print_shared(st, "ArgInfoData"); int nargs = number_of_args(); for (int i = 0; i < nargs; i++) { @@ -407,7 +530,11 @@ int MethodData::bytecode_cell_count(Bytecodes::Code code) { } case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: - return CounterData::static_cell_count(); + if (MethodData::profile_arguments()) { + return variable_cell_count; + } else { + return CounterData::static_cell_count(); + } case Bytecodes::_goto: case Bytecodes::_goto_w: case Bytecodes::_jsr: @@ -415,9 +542,17 @@ int MethodData::bytecode_cell_count(Bytecodes::Code code) { return JumpData::static_cell_count(); case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: - return VirtualCallData::static_cell_count(); + if (MethodData::profile_arguments()) { + return variable_cell_count; + } else { + return VirtualCallData::static_cell_count(); + } case Bytecodes::_invokedynamic: - return CounterData::static_cell_count(); + if (MethodData::profile_arguments()) { + return variable_cell_count; + } else { + return CounterData::static_cell_count(); + } case Bytecodes::_ret: return RetData::static_cell_count(); case Bytecodes::_ifeq: @@ -453,7 +588,34 @@ int MethodData::compute_data_size(BytecodeStream* stream) { return 0; } if (cell_count == variable_cell_count) { - cell_count = MultiBranchData::compute_cell_count(stream); + switch (stream->code()) { + case Bytecodes::_lookupswitch: + case Bytecodes::_tableswitch: + cell_count = MultiBranchData::compute_cell_count(stream); + break; + case Bytecodes::_invokespecial: + case Bytecodes::_invokestatic: + case Bytecodes::_invokedynamic: + assert(MethodData::profile_arguments(), "should be collecting args profile"); + if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + cell_count = CallTypeData::compute_cell_count(stream); + } else { + cell_count = CounterData::static_cell_count(); + } + break; + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: { + assert(MethodData::profile_arguments(), "should be collecting args profile"); + if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + cell_count = VirtualCallTypeData::compute_cell_count(stream); + } else { + cell_count = VirtualCallData::static_cell_count(); + } + break; + } + default: + fatal("unexpected bytecode for var length profile data"); + } } // Note: cell_count might be zero, meaning that there is just // a DataLayout header, with no extra cells. @@ -499,6 +661,7 @@ int MethodData::compute_allocation_size_in_bytes(methodHandle method) { // Add a cell to record information about modified arguments. int arg_size = method->size_of_parameters(); object_size += DataLayout::compute_size_in_bytes(arg_size+1); + return object_size; } @@ -534,10 +697,20 @@ int MethodData::initialize_data(BytecodeStream* stream, } break; case Bytecodes::_invokespecial: - case Bytecodes::_invokestatic: - cell_count = CounterData::static_cell_count(); - tag = DataLayout::counter_data_tag; + case Bytecodes::_invokestatic: { + int counter_data_cell_count = CounterData::static_cell_count(); + if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + cell_count = CallTypeData::compute_cell_count(stream); + } else { + cell_count = counter_data_cell_count; + } + if (cell_count > counter_data_cell_count) { + tag = DataLayout::call_type_data_tag; + } else { + tag = DataLayout::counter_data_tag; + } break; + } case Bytecodes::_goto: case Bytecodes::_goto_w: case Bytecodes::_jsr: @@ -546,15 +719,35 @@ int MethodData::initialize_data(BytecodeStream* stream, tag = DataLayout::jump_data_tag; break; case Bytecodes::_invokevirtual: - case Bytecodes::_invokeinterface: - cell_count = VirtualCallData::static_cell_count(); - tag = DataLayout::virtual_call_data_tag; + case Bytecodes::_invokeinterface: { + int virtual_call_data_cell_count = VirtualCallData::static_cell_count(); + if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + cell_count = VirtualCallTypeData::compute_cell_count(stream); + } else { + cell_count = virtual_call_data_cell_count; + } + if (cell_count > virtual_call_data_cell_count) { + tag = DataLayout::virtual_call_type_data_tag; + } else { + tag = DataLayout::virtual_call_data_tag; + } break; - case Bytecodes::_invokedynamic: + } + case Bytecodes::_invokedynamic: { // %%% should make a type profile for any invokedynamic that takes a ref argument - cell_count = CounterData::static_cell_count(); - tag = DataLayout::counter_data_tag; + int counter_data_cell_count = CounterData::static_cell_count(); + if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + cell_count = CallTypeData::compute_cell_count(stream); + } else { + cell_count = counter_data_cell_count; + } + if (cell_count > counter_data_cell_count) { + tag = DataLayout::call_type_data_tag; + } else { + tag = DataLayout::counter_data_tag; + } break; + } case Bytecodes::_ret: cell_count = RetData::static_cell_count(); tag = DataLayout::ret_data_tag; @@ -585,6 +778,11 @@ int MethodData::initialize_data(BytecodeStream* stream, break; } assert(tag == DataLayout::multi_branch_data_tag || + (MethodData::profile_arguments() && + (tag == DataLayout::call_type_data_tag || + tag == DataLayout::counter_data_tag || + tag == DataLayout::virtual_call_type_data_tag || + tag == DataLayout::virtual_call_data_tag)) || cell_count == bytecode_cell_count(c), "cell counts must agree"); if (cell_count >= 0) { assert(tag != DataLayout::no_tag, "bad tag"); @@ -631,6 +829,10 @@ ProfileData* DataLayout::data_in() { return new MultiBranchData(this); case DataLayout::arg_info_data_tag: return new ArgInfoData(this); + case DataLayout::call_type_data_tag: + return new CallTypeData(this); + case DataLayout::virtual_call_type_data_tag: + return new VirtualCallTypeData(this); }; } @@ -898,3 +1100,42 @@ void MethodData::verify_data_on(outputStream* st) { NEEDS_CLEANUP; // not yet implemented. } + +bool MethodData::profile_jsr292(methodHandle m, int bci) { + if (m->is_compiled_lambda_form()) { + return true; + } + + Bytecode_invoke inv(m , bci); + return inv.is_invokedynamic() || inv.is_invokehandle(); +} + +int MethodData::profile_arguments_flag() { + return TypeProfileLevel; +} + +bool MethodData::profile_arguments() { + return profile_arguments_flag() > no_type_profile && profile_arguments_flag() <= type_profile_all; +} + +bool MethodData::profile_arguments_jsr292_only() { + return profile_arguments_flag() == type_profile_jsr292; +} + +bool MethodData::profile_all_arguments() { + return profile_arguments_flag() == type_profile_all; +} + +bool MethodData::profile_arguments_for_invoke(methodHandle m, int bci) { + if (!profile_arguments()) { + return false; + } + + if (profile_all_arguments()) { + return true; + } + + assert(profile_arguments_jsr292_only(), "inconsistent"); + return profile_jsr292(m, bci); +} + diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 76f9b1f221a..2064d4365d6 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -117,7 +117,9 @@ public: ret_data_tag, branch_data_tag, multi_branch_data_tag, - arg_info_data_tag + arg_info_data_tag, + call_type_data_tag, + virtual_call_type_data_tag }; enum { @@ -165,7 +167,7 @@ public: // occurred, and the MDO shows N occurrences of X, we make the // simplifying assumption that all N occurrences can be blamed // on that BCI. - int trap_state() { + int trap_state() const { return ((_header._struct._flags >> trap_shift) & trap_mask); } @@ -175,11 +177,11 @@ public: _header._struct._flags = (new_state << trap_shift) | old_flags; } - u1 flags() { + u1 flags() const { return _header._struct._flags; } - u2 bci() { + u2 bci() const { return _header._struct._bci; } @@ -198,7 +200,7 @@ public: void release_set_cell_at(int index, intptr_t value) { OrderAccess::release_store_ptr(&_cells[index], value); } - intptr_t cell_at(int index) { + intptr_t cell_at(int index) const { return _cells[index]; } @@ -206,7 +208,7 @@ public: assert(flag_number < flag_limit, "oob"); _header._struct._flags |= (0x1 << flag_number); } - bool flag_at(int flag_number) { + bool flag_at(int flag_number) const { assert(flag_number < flag_limit, "oob"); return (_header._struct._flags & (0x1 << flag_number)) != 0; } @@ -254,19 +256,22 @@ class BitData; class CounterData; class ReceiverTypeData; class VirtualCallData; +class VirtualCallTypeData; class RetData; +class CallTypeData; class JumpData; class BranchData; class ArrayData; class MultiBranchData; class ArgInfoData; - // ProfileData // // A ProfileData object is created to refer to a section of profiling // data in a structured way. class ProfileData : public ResourceObj { + friend class TypeEntries; + friend class TypeStackSlotEntries; private: #ifndef PRODUCT enum { @@ -280,6 +285,7 @@ private: protected: DataLayout* data() { return _data; } + const DataLayout* data() const { return _data; } enum { cell_size = DataLayout::cell_size @@ -287,7 +293,7 @@ protected: public: // How many cells are in this? - virtual int cell_count() { + virtual int cell_count() const { ShouldNotReachHere(); return -1; } @@ -307,7 +313,7 @@ protected: assert(0 <= index && index < cell_count(), "oob"); data()->release_set_cell_at(index, value); } - intptr_t intptr_at(int index) { + intptr_t intptr_at(int index) const { assert(0 <= index && index < cell_count(), "oob"); return data()->cell_at(index); } @@ -317,7 +323,7 @@ protected: void release_set_uint_at(int index, uint value) { release_set_intptr_at(index, (intptr_t) value); } - uint uint_at(int index) { + uint uint_at(int index) const { return (uint)intptr_at(index); } void set_int_at(int index, int value) { @@ -326,23 +332,23 @@ protected: void release_set_int_at(int index, int value) { release_set_intptr_at(index, (intptr_t) value); } - int int_at(int index) { + int int_at(int index) const { return (int)intptr_at(index); } - int int_at_unchecked(int index) { + int int_at_unchecked(int index) const { return (int)data()->cell_at(index); } void set_oop_at(int index, oop value) { set_intptr_at(index, cast_from_oop(value)); } - oop oop_at(int index) { + oop oop_at(int index) const { return cast_to_oop(intptr_at(index)); } void set_flag_at(int flag_number) { data()->set_flag_at(flag_number); } - bool flag_at(int flag_number) { + bool flag_at(int flag_number) const { return data()->flag_at(flag_number); } @@ -362,7 +368,7 @@ public: // Constructor for invalid ProfileData. ProfileData(); - u2 bci() { + u2 bci() const { return data()->bci(); } @@ -370,7 +376,7 @@ public: return (address)_data; } - int trap_state() { + int trap_state() const { return data()->trap_state(); } void set_trap_state(int new_state) { @@ -378,58 +384,68 @@ public: } // Type checking - virtual bool is_BitData() { return false; } - virtual bool is_CounterData() { return false; } - virtual bool is_JumpData() { return false; } - virtual bool is_ReceiverTypeData(){ return false; } - virtual bool is_VirtualCallData() { return false; } - virtual bool is_RetData() { return false; } - virtual bool is_BranchData() { return false; } - virtual bool is_ArrayData() { return false; } - virtual bool is_MultiBranchData() { return false; } - virtual bool is_ArgInfoData() { return false; } + virtual bool is_BitData() const { return false; } + virtual bool is_CounterData() const { return false; } + virtual bool is_JumpData() const { return false; } + virtual bool is_ReceiverTypeData()const { return false; } + virtual bool is_VirtualCallData() const { return false; } + virtual bool is_RetData() const { return false; } + virtual bool is_BranchData() const { return false; } + virtual bool is_ArrayData() const { return false; } + virtual bool is_MultiBranchData() const { return false; } + virtual bool is_ArgInfoData() const { return false; } + virtual bool is_CallTypeData() const { return false; } + virtual bool is_VirtualCallTypeData()const { return false; } - BitData* as_BitData() { + BitData* as_BitData() const { assert(is_BitData(), "wrong type"); return is_BitData() ? (BitData*) this : NULL; } - CounterData* as_CounterData() { + CounterData* as_CounterData() const { assert(is_CounterData(), "wrong type"); return is_CounterData() ? (CounterData*) this : NULL; } - JumpData* as_JumpData() { + JumpData* as_JumpData() const { assert(is_JumpData(), "wrong type"); return is_JumpData() ? (JumpData*) this : NULL; } - ReceiverTypeData* as_ReceiverTypeData() { + ReceiverTypeData* as_ReceiverTypeData() const { assert(is_ReceiverTypeData(), "wrong type"); return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; } - VirtualCallData* as_VirtualCallData() { + VirtualCallData* as_VirtualCallData() const { assert(is_VirtualCallData(), "wrong type"); return is_VirtualCallData() ? (VirtualCallData*)this : NULL; } - RetData* as_RetData() { + RetData* as_RetData() const { assert(is_RetData(), "wrong type"); return is_RetData() ? (RetData*) this : NULL; } - BranchData* as_BranchData() { + BranchData* as_BranchData() const { assert(is_BranchData(), "wrong type"); return is_BranchData() ? (BranchData*) this : NULL; } - ArrayData* as_ArrayData() { + ArrayData* as_ArrayData() const { assert(is_ArrayData(), "wrong type"); return is_ArrayData() ? (ArrayData*) this : NULL; } - MultiBranchData* as_MultiBranchData() { + MultiBranchData* as_MultiBranchData() const { assert(is_MultiBranchData(), "wrong type"); return is_MultiBranchData() ? (MultiBranchData*)this : NULL; } - ArgInfoData* as_ArgInfoData() { + ArgInfoData* as_ArgInfoData() const { assert(is_ArgInfoData(), "wrong type"); return is_ArgInfoData() ? (ArgInfoData*)this : NULL; } + CallTypeData* as_CallTypeData() const { + assert(is_CallTypeData(), "wrong type"); + return is_CallTypeData() ? (CallTypeData*)this : NULL; + } + VirtualCallTypeData* as_VirtualCallTypeData() const { + assert(is_VirtualCallTypeData(), "wrong type"); + return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; + } // Subclass specific initialization @@ -443,15 +459,15 @@ public: // an oop in a ProfileData to the ci equivalent. Generally speaking, // most ProfileData don't require any translation, so we provide the null // translation here, and the required translators are in the ci subclasses. - virtual void translate_from(ProfileData* data) {} + virtual void translate_from(const ProfileData* data) {} - virtual void print_data_on(outputStream* st) { + virtual void print_data_on(outputStream* st) const { ShouldNotReachHere(); } #ifndef PRODUCT - void print_shared(outputStream* st, const char* name); - void tab(outputStream* st); + void print_shared(outputStream* st, const char* name) const; + void tab(outputStream* st, bool first = false) const; #endif }; @@ -470,13 +486,13 @@ public: BitData(DataLayout* layout) : ProfileData(layout) { } - virtual bool is_BitData() { return true; } + virtual bool is_BitData() const { return true; } static int static_cell_count() { return bit_cell_count; } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } @@ -498,7 +514,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; #endif }; @@ -514,18 +530,18 @@ protected: public: CounterData(DataLayout* layout) : BitData(layout) {} - virtual bool is_CounterData() { return true; } + virtual bool is_CounterData() const { return true; } static int static_cell_count() { return counter_cell_count; } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } // Direct accessor - uint count() { + uint count() const { return uint_at(count_off); } @@ -542,7 +558,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; #endif }; @@ -570,18 +586,18 @@ public: layout->tag() == DataLayout::branch_data_tag, "wrong type"); } - virtual bool is_JumpData() { return true; } + virtual bool is_JumpData() const { return true; } static int static_cell_count() { return jump_cell_count; } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } // Direct accessor - uint taken() { + uint taken() const { return uint_at(taken_off_set); } @@ -598,7 +614,7 @@ public: return cnt; } - int displacement() { + int displacement() const { return int_at(displacement_off_set); } @@ -615,7 +631,332 @@ public: void post_initialize(BytecodeStream* stream, MethodData* mdo); #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; +#endif +}; + +// Entries in a ProfileData object to record types: it can either be +// none (no profile), unknown (conflicting profile data) or a klass if +// a single one is seen. Whether a null reference was seen is also +// recorded. No counter is associated with the type and a single type +// is tracked (unlike VirtualCallData). +class TypeEntries { + +public: + + // A single cell is used to record information for a type: + // - the cell is initialized to 0 + // - when a type is discovered it is stored in the cell + // - bit zero of the cell is used to record whether a null reference + // was encountered or not + // - bit 1 is set to record a conflict in the type information + + enum { + null_seen = 1, + type_mask = ~null_seen, + type_unknown = 2, + status_bits = null_seen | type_unknown, + type_klass_mask = ~status_bits + }; + + // what to initialize a cell to + static intptr_t type_none() { + return 0; + } + + // null seen = bit 0 set? + static bool was_null_seen(intptr_t v) { + return (v & null_seen) != 0; + } + + // conflicting type information = bit 1 set? + static bool is_type_unknown(intptr_t v) { + return (v & type_unknown) != 0; + } + + // not type information yet = all bits cleared, ignoring bit 0? + static bool is_type_none(intptr_t v) { + return (v & type_mask) == 0; + } + + // recorded type: cell without bit 0 and 1 + static intptr_t klass_part(intptr_t v) { + intptr_t r = v & type_klass_mask; + assert (r != 0, "invalid"); + return r; + } + + // type recorded + static Klass* valid_klass(intptr_t k) { + if (!is_type_none(k) && + !is_type_unknown(k)) { + return (Klass*)klass_part(k); + } else { + return NULL; + } + } + + static intptr_t with_status(intptr_t k, intptr_t in) { + return k | (in & status_bits); + } + + static intptr_t with_status(Klass* k, intptr_t in) { + return with_status((intptr_t)k, in); + } + +#ifndef PRODUCT + static void print_klass(outputStream* st, intptr_t k); +#endif + + // GC support + static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p); + +protected: + // ProfileData object these entries are part of + ProfileData* _pd; + // offset within the ProfileData object where the entries start + const int _base_off; + + TypeEntries(int base_off) + : _base_off(base_off), _pd(NULL) {} + + void set_intptr_at(int index, intptr_t value) { + _pd->set_intptr_at(index, value); + } + + intptr_t intptr_at(int index) const { + return _pd->intptr_at(index); + } + +public: + void set_profile_data(ProfileData* pd) { + _pd = pd; + } +}; + +// Type entries used for arguments passed at a call and parameters on +// method entry. 2 cells per entry: one for the type encoded as in +// TypeEntries and one initialized with the stack slot where the +// profiled object is to be found so that the interpreter can locate +// it quickly. +class TypeStackSlotEntries : public TypeEntries { + +private: + enum { + stack_slot_entry, + type_entry, + per_arg_cell_count + }; + + // Start with a header if needed. It stores the number of cells used + // for this call type information. Unless we collect only profiling + // for a single argument the number of cells is unknown statically. + static int header_cell_count() { + return (TypeProfileArgsLimit > 1) ? 1 : 0; + } + + static int cell_count_local_offset() { + assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count"); + return 0; + } + + int cell_count_global_offset() const { + return _base_off + cell_count_local_offset(); + } + + // offset of cell for stack slot for entry i within ProfileData object + int stack_slot_global_offset(int i) const { + return _base_off + stack_slot_local_offset(i); + } + + void check_number_of_arguments(int total) { + assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); + } + + // number of cells not counting the header + int cell_count_no_header() const { + return _pd->uint_at(cell_count_global_offset()); + } + + static bool arguments_profiling_enabled(); + static void assert_arguments_profiling_enabled() { + assert(arguments_profiling_enabled(), "args profiling should be on"); + } + +protected: + + // offset of cell for type for entry i within ProfileData object + int type_global_offset(int i) const { + return _base_off + type_local_offset(i); + } + +public: + + TypeStackSlotEntries(int base_off) + : TypeEntries(base_off) {} + + static int compute_cell_count(BytecodeStream* stream); + + static void initialize(DataLayout* dl, int base, int cell_count) { + if (TypeProfileArgsLimit > 1) { + int off = base + cell_count_local_offset(); + dl->set_cell_at(off, cell_count - base - header_cell_count()); + } + } + + void post_initialize(BytecodeStream* stream); + + int number_of_arguments() const { + assert_arguments_profiling_enabled(); + if (TypeProfileArgsLimit > 1) { + int cell_count = cell_count_no_header(); + int nb = cell_count / TypeStackSlotEntries::per_arg_count(); + assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args"); + return nb; + } else { + assert(TypeProfileArgsLimit == 1, "at least one arg"); + return 1; + } + } + + int cell_count() const { + assert_arguments_profiling_enabled(); + if (TypeProfileArgsLimit > 1) { + return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset()); + } else { + return _base_off + TypeStackSlotEntries::per_arg_count(); + } + } + + // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries + static int stack_slot_local_offset(int i) { + assert_arguments_profiling_enabled(); + return header_cell_count() + i * per_arg_cell_count + stack_slot_entry; + } + + // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries + static int type_local_offset(int i) { + return header_cell_count() + i * per_arg_cell_count + type_entry; + } + + // stack slot for entry i + uint stack_slot(int i) const { + assert(i >= 0 && i < number_of_arguments(), "oob"); + return _pd->uint_at(stack_slot_global_offset(i)); + } + + // set stack slot for entry i + void set_stack_slot(int i, uint num) { + assert(i >= 0 && i < number_of_arguments(), "oob"); + _pd->set_uint_at(stack_slot_global_offset(i), num); + } + + // type for entry i + intptr_t type(int i) const { + assert(i >= 0 && i < number_of_arguments(), "oob"); + return _pd->intptr_at(type_global_offset(i)); + } + + // set type for entry i + void set_type(int i, intptr_t k) { + assert(i >= 0 && i < number_of_arguments(), "oob"); + _pd->set_intptr_at(type_global_offset(i), k); + } + + static ByteSize per_arg_size() { + return in_ByteSize(per_arg_cell_count * DataLayout::cell_size); + } + + static int per_arg_count() { + return per_arg_cell_count ; + } + + // Code generation support + static ByteSize cell_count_offset() { + return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); + } + + static ByteSize args_data_offset() { + return in_ByteSize(header_cell_count() * DataLayout::cell_size); + } + + static ByteSize stack_slot_offset(int i) { + return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); + } + + static ByteSize type_offset(int i) { + return in_ByteSize(type_local_offset(i) * DataLayout::cell_size); + } + + // GC support + void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); + +#ifndef PRODUCT + void print_data_on(outputStream* st) const; +#endif +}; + +// CallTypeData +// +// A CallTypeData is used to access profiling information about a non +// virtual call for which we collect type information about arguments. +class CallTypeData : public CounterData { +private: + TypeStackSlotEntries _args; + +public: + CallTypeData(DataLayout* layout) : + CounterData(layout), _args(CounterData::static_cell_count()) { + assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); + // Some compilers (VC++) don't want this passed in member initialization list + _args.set_profile_data(this); + } + + const TypeStackSlotEntries* args() const { return &_args; } + + virtual bool is_CallTypeData() const { return true; } + + static int static_cell_count() { + return -1; + } + + static int compute_cell_count(BytecodeStream* stream) { + return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); + } + + static void initialize(DataLayout* dl, int cell_count) { + TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count); + } + + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { + _args.post_initialize(stream); + } + + virtual int cell_count() const { + return _args.cell_count(); + } + + uint number_of_arguments() const { + return args()->number_of_arguments(); + } + + void set_argument_type(int i, Klass* k) { + intptr_t current = _args.type(i); + _args.set_type(i, TypeEntries::with_status(k, current)); + } + + // Code generation support + static ByteSize args_data_offset() { + return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); + } + + // GC support + virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { + _args.clean_weak_klass_links(is_alive_closure); + } + +#ifndef PRODUCT + virtual void print_data_on(outputStream* st) const; #endif }; @@ -636,16 +977,17 @@ protected: public: ReceiverTypeData(DataLayout* layout) : CounterData(layout) { assert(layout->tag() == DataLayout::receiver_type_data_tag || - layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); + layout->tag() == DataLayout::virtual_call_data_tag || + layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); } - virtual bool is_ReceiverTypeData() { return true; } + virtual bool is_ReceiverTypeData() const { return true; } static int static_cell_count() { return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } @@ -660,7 +1002,7 @@ public: return count0_offset + row * receiver_type_row_cell_count; } - Klass* receiver(uint row) { + Klass* receiver(uint row) const { assert(row < row_limit(), "oob"); Klass* recv = (Klass*)intptr_at(receiver_cell_index(row)); @@ -673,7 +1015,7 @@ public: set_intptr_at(receiver_cell_index(row), (uintptr_t)k); } - uint receiver_count(uint row) { + uint receiver_count(uint row) const { assert(row < row_limit(), "oob"); return uint_at(receiver_count_cell_index(row)); } @@ -721,8 +1063,8 @@ public: virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); #ifndef PRODUCT - void print_receiver_data_on(outputStream* st); - void print_data_on(outputStream* st); + void print_receiver_data_on(outputStream* st) const; + void print_data_on(outputStream* st) const; #endif }; @@ -733,10 +1075,11 @@ public: class VirtualCallData : public ReceiverTypeData { public: VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { - assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); + assert(layout->tag() == DataLayout::virtual_call_data_tag || + layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); } - virtual bool is_VirtualCallData() { return true; } + virtual bool is_VirtualCallData() const { return true; } static int static_cell_count() { // At this point we could add more profile state, e.g., for arguments. @@ -744,7 +1087,7 @@ public: return ReceiverTypeData::static_cell_count(); } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } @@ -754,7 +1097,73 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; +#endif +}; + +// VirtualCallTypeData +// +// A VirtualCallTypeData is used to access profiling information about +// a virtual call for which we collect type information about +// arguments. +class VirtualCallTypeData : public VirtualCallData { +private: + TypeStackSlotEntries _args; + +public: + VirtualCallTypeData(DataLayout* layout) : + VirtualCallData(layout), _args(VirtualCallData::static_cell_count()) { + assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); + // Some compilers (VC++) don't want this passed in member initialization list + _args.set_profile_data(this); + } + + const TypeStackSlotEntries* args() const { return &_args; } + + virtual bool is_VirtualCallTypeData() const { return true; } + + static int static_cell_count() { + return -1; + } + + static int compute_cell_count(BytecodeStream* stream) { + return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); + } + + static void initialize(DataLayout* dl, int cell_count) { + TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count); + } + + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { + _args.post_initialize(stream); + } + + virtual int cell_count() const { + return _args.cell_count(); + } + + uint number_of_arguments() const { + return args()->number_of_arguments(); + } + + void set_argument_type(int i, Klass* k) { + intptr_t current = _args.type(i); + _args.set_type(i, TypeEntries::with_status(k, current)); + } + + // Code generation support + static ByteSize args_data_offset() { + return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); + } + + // GC support + virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { + ReceiverTypeData::clean_weak_klass_links(is_alive_closure); + _args.clean_weak_klass_links(is_alive_closure); + } + +#ifndef PRODUCT + virtual void print_data_on(outputStream* st) const; #endif }; @@ -797,7 +1206,7 @@ public: assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); } - virtual bool is_RetData() { return true; } + virtual bool is_RetData() const { return true; } enum { no_bci = -1 // value of bci when bci1/2 are not in use. @@ -807,7 +1216,7 @@ public: return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } @@ -825,13 +1234,13 @@ public: } // Direct accessors - int bci(uint row) { + int bci(uint row) const { return int_at(bci_cell_index(row)); } - uint bci_count(uint row) { + uint bci_count(uint row) const { return uint_at(bci_count_cell_index(row)); } - int bci_displacement(uint row) { + int bci_displacement(uint row) const { return int_at(bci_displacement_cell_index(row)); } @@ -853,7 +1262,7 @@ public: void post_initialize(BytecodeStream* stream, MethodData* mdo); #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; #endif }; @@ -878,18 +1287,18 @@ public: assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); } - virtual bool is_BranchData() { return true; } + virtual bool is_BranchData() const { return true; } static int static_cell_count() { return branch_cell_count; } - virtual int cell_count() { + virtual int cell_count() const { return static_cell_count(); } // Direct accessor - uint not_taken() { + uint not_taken() const { return uint_at(not_taken_off_set); } @@ -917,7 +1326,7 @@ public: void post_initialize(BytecodeStream* stream, MethodData* mdo); #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; #endif }; @@ -935,15 +1344,15 @@ protected: array_start_off_set }; - uint array_uint_at(int index) { + uint array_uint_at(int index) const { int aindex = index + array_start_off_set; return uint_at(aindex); } - int array_int_at(int index) { + int array_int_at(int index) const { int aindex = index + array_start_off_set; return int_at(aindex); } - oop array_oop_at(int index) { + oop array_oop_at(int index) const { int aindex = index + array_start_off_set; return oop_at(aindex); } @@ -960,17 +1369,17 @@ protected: public: ArrayData(DataLayout* layout) : ProfileData(layout) {} - virtual bool is_ArrayData() { return true; } + virtual bool is_ArrayData() const { return true; } static int static_cell_count() { return -1; } - int array_len() { + int array_len() const { return int_at_unchecked(array_len_off_set); } - virtual int cell_count() { + virtual int cell_count() const { return array_len() + 1; } @@ -1017,29 +1426,29 @@ public: assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); } - virtual bool is_MultiBranchData() { return true; } + virtual bool is_MultiBranchData() const { return true; } static int compute_cell_count(BytecodeStream* stream); - int number_of_cases() { + int number_of_cases() const { int alen = array_len() - 2; // get rid of default case here. assert(alen % per_case_cell_count == 0, "must be even"); return (alen / per_case_cell_count); } - uint default_count() { + uint default_count() const { return array_uint_at(default_count_off_set); } - int default_displacement() { + int default_displacement() const { return array_int_at(default_disaplacement_off_set); } - uint count_at(int index) { + uint count_at(int index) const { return array_uint_at(case_array_start + index * per_case_cell_count + relative_count_off_set); } - int displacement_at(int index) { + int displacement_at(int index) const { return array_int_at(case_array_start + index * per_case_cell_count + relative_displacement_off_set); @@ -1074,7 +1483,7 @@ public: void post_initialize(BytecodeStream* stream, MethodData* mdo); #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; #endif }; @@ -1085,14 +1494,14 @@ public: assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); } - virtual bool is_ArgInfoData() { return true; } + virtual bool is_ArgInfoData() const { return true; } - int number_of_args() { + int number_of_args() const { return array_len(); } - uint arg_modified(int arg) { + uint arg_modified(int arg) const { return array_uint_at(arg); } @@ -1101,7 +1510,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st); + void print_data_on(outputStream* st) const; #endif }; @@ -1271,6 +1680,18 @@ private: // return the argument info cell ArgInfoData *arg_info(); + enum { + no_type_profile = 0, + type_profile_jsr292 = 1, + type_profile_all = 2 + }; + + static bool profile_jsr292(methodHandle m, int bci); + static int profile_arguments_flag(); + static bool profile_arguments_jsr292_only(); + static bool profile_all_arguments(); + static bool profile_arguments_for_invoke(methodHandle m, int bci); + public: static int header_size() { return sizeof(MethodData)/wordSize; @@ -1510,6 +1931,8 @@ public: // verification void verify_on(outputStream* st); void verify_data_on(outputStream* st); + + static bool profile_arguments(); }; #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index e8b7d171934..181ce69a8f4 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2648,6 +2648,13 @@ class CommandLineFlags { product(bool, AggressiveOpts, false, \ "Enable aggressive optimizations - see arguments.cpp") \ \ + product_pd(uintx, TypeProfileLevel, \ + "Type profiling of arguments at call:" \ + "0->off ; 1->js292 only; 2->all methods") \ + \ + product(intx, TypeProfileArgsLimit, 2, \ + "max number of call arguments to consider for type profiling") \ + \ /* statistics */ \ develop(bool, CountCompiledCalls, false, \ "counts method invocations") \ @@ -3760,7 +3767,6 @@ class CommandLineFlags { product(bool, UseLockedTracing, false, \ "Use locked-tracing when doing event-based tracing") - /* * Macros for factoring of globals */ diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index 874765fa3e5..e33e935fb6f 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -183,6 +183,7 @@ void print_method_profiling_data() { collected_profiled_methods->sort(&compare_methods); int count = collected_profiled_methods->length(); + int total_size = 0; if (count > 0) { for (int index = 0; index < count; index++) { Method* m = collected_profiled_methods->at(index); @@ -190,10 +191,13 @@ void print_method_profiling_data() { tty->print_cr("------------------------------------------------------------------------"); //m->print_name(tty); m->print_invocation_count(); + tty->print_cr(" mdo size: %d bytes", m->method_data()->size_in_bytes()); tty->cr(); m->print_codes(); + total_size += m->method_data()->size_in_bytes(); } tty->print_cr("------------------------------------------------------------------------"); + tty->print_cr("Total MDO size: %d bytes", total_size); } } diff --git a/hotspot/src/share/vm/runtime/signature.cpp b/hotspot/src/share/vm/runtime/signature.cpp index ce1b069ee6b..388058aa538 100644 --- a/hotspot/src/share/vm/runtime/signature.cpp +++ b/hotspot/src/share/vm/runtime/signature.cpp @@ -378,6 +378,16 @@ Symbol* SignatureStream::as_symbol_or_null() { return result; } +int SignatureStream::reference_parameter_count() { + int args_count = 0; + for ( ; !at_return_type(); next()) { + if (is_object()) { + args_count++; + } + } + return args_count; +} + bool SignatureVerifier::is_valid_signature(Symbol* sig) { const char* signature = (const char*)sig->bytes(); ssize_t len = sig->utf8_length(); diff --git a/hotspot/src/share/vm/runtime/signature.hpp b/hotspot/src/share/vm/runtime/signature.hpp index 33c8c8232ca..4bd4d4bab1f 100644 --- a/hotspot/src/share/vm/runtime/signature.hpp +++ b/hotspot/src/share/vm/runtime/signature.hpp @@ -401,6 +401,9 @@ class SignatureStream : public StackObj { // return same as_symbol except allocation of new symbols is avoided. Symbol* as_symbol_or_null(); + + // count the number of references in the signature + int reference_parameter_count(); }; class SignatureVerifier : public StackObj { From 16ce875fc6a8d7da100a634757e14f80d1377fad Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Wed, 9 Oct 2013 17:53:22 +0200 Subject: [PATCH 034/152] 8026137: Fix Issues with Binary Evaluation Order Co-authored-by: Attila Szegedi Reviewed-by: hannesw, jlaskey --- .../jdk/nashorn/internal/codegen/Attr.java | 135 +++- .../internal/codegen/BranchOptimizer.java | 39 +- .../internal/codegen/CodeGenerator.java | 342 ++++---- .../nashorn/internal/codegen/CompileUnit.java | 7 +- .../nashorn/internal/codegen/Compiler.java | 10 +- .../internal/codegen/FinalizeTypes.java | 755 +----------------- .../internal/codegen/MethodEmitter.java | 10 +- .../nashorn/internal/codegen/WeighNodes.java | 5 - .../internal/codegen/types/BooleanType.java | 3 +- .../internal/codegen/types/ObjectType.java | 3 +- .../nashorn/internal/codegen/types/Type.java | 7 +- .../jdk/nashorn/internal/ir/AccessNode.java | 27 +- .../src/jdk/nashorn/internal/ir/BaseNode.java | 38 +- .../src/jdk/nashorn/internal/ir/CallNode.java | 44 +- .../jdk/nashorn/internal/ir/IdentNode.java | 42 +- .../jdk/nashorn/internal/ir/IndexNode.java | 27 +- .../jdk/nashorn/internal/ir/LiteralNode.java | 17 +- .../jdk/nashorn/internal/ir/RuntimeNode.java | 63 +- .../jdk/nashorn/internal/ir/TypeOverride.java | 62 -- .../jdk/nashorn/internal/ir/UnaryNode.java | 22 +- .../ir/visitor/NodeOperatorVisitor.java | 24 - .../nashorn/internal/parser/TokenType.java | 1 - .../jdk/nashorn/internal/runtime/Context.java | 10 +- .../jdk/nashorn/internal/runtime/JSType.java | 20 +- .../runtime/arrays/JavaArrayIterator.java | 2 +- .../arrays/ReverseJavaArrayIterator.java | 2 +- .../runtime/linker/JSObjectLinker.java | 4 +- nashorn/test/script/basic/JDK-8026137.js | 44 + .../test/script/basic/JDK-8026137.js.EXPECTED | 2 + 29 files changed, 450 insertions(+), 1317 deletions(-) delete mode 100644 nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java create mode 100644 nashorn/test/script/basic/JDK-8026137.js create mode 100644 nashorn/test/script/basic/JDK-8026137.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 7aef4603b28..5415a06df41 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -480,6 +480,10 @@ final class Attr extends NodeOperatorVisitor { } //unknown parameters are promoted to object type. + if (newFunctionNode.hasLazyChildren()) { + //the final body has already been assigned as we have left the function node block body by now + objectifySymbols(body); + } newFunctionNode = finalizeParameters(newFunctionNode); newFunctionNode = finalizeTypes(newFunctionNode); for (final Symbol symbol : newFunctionNode.getDeclaredSymbols()) { @@ -489,11 +493,6 @@ final class Attr extends NodeOperatorVisitor { } } - if (newFunctionNode.hasLazyChildren()) { - //the final body has already been assigned as we have left the function node block body by now - objectifySymbols(body); - } - List syntheticInitializers = null; if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) { @@ -503,8 +502,8 @@ final class Attr extends NodeOperatorVisitor { syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode)); } - if(newFunctionNode.needsArguments()) { - if(syntheticInitializers == null) { + if (newFunctionNode.needsArguments()) { + if (syntheticInitializers == null) { syntheticInitializers = new ArrayList<>(1); } // "var arguments = :arguments" @@ -512,12 +511,12 @@ final class Attr extends NodeOperatorVisitor { ARGUMENTS, newFunctionNode)); } - if(syntheticInitializers != null) { - final List stmts = body.getStatements(); + if (syntheticInitializers != null) { + final List stmts = newFunctionNode.getBody().getStatements(); final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); newStatements.addAll(syntheticInitializers); newStatements.addAll(stmts); - newFunctionNode = newFunctionNode.setBody(lc, body.setStatements(lc, newStatements)); + newFunctionNode = newFunctionNode.setBody(lc, newFunctionNode.getBody().setStatements(lc, newStatements)); } if (returnTypes.peek().isUnknown()) { @@ -557,12 +556,6 @@ final class Attr extends NodeOperatorVisitor { return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol)); } - @Override - public Node leaveCONVERT(final UnaryNode unaryNode) { - assert false : "There should be no convert operators in IR during Attribution"; - return end(unaryNode); - } - @Override public Node leaveIdentNode(final IdentNode identNode) { final String name = identNode.getName(); @@ -991,7 +984,7 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveNEW(final UnaryNode unaryNode) { - return end(ensureSymbol(Type.OBJECT, unaryNode)); + return end(ensureSymbol(Type.OBJECT, unaryNode.setRHS(((CallNode)unaryNode.rhs()).setIsNew()))); } @Override @@ -1287,7 +1280,9 @@ final class Attr extends NodeOperatorVisitor { private Node leaveCmp(final BinaryNode binaryNode) { ensureTypeNotUnknown(binaryNode.lhs()); ensureTypeNotUnknown(binaryNode.rhs()); - + Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()); + ensureSymbol(widest, binaryNode.lhs()); + ensureSymbol(widest, binaryNode.rhs()); return end(ensureSymbol(Type.BOOLEAN, binaryNode)); } @@ -1630,7 +1625,7 @@ final class Attr extends NodeOperatorVisitor { if (!Type.areEquivalent(from, to) && Type.widest(from, to) == to) { LOG.fine("Had to post pass widen '", node, "' ", Debug.id(node), " from ", node.getType(), " to ", to); Symbol symbol = node.getSymbol(); - if(symbol.isShared() && symbol.wouldChangeType(to)) { + if (symbol.isShared() && symbol.wouldChangeType(to)) { symbol = temporarySymbols.getTypedTemporarySymbol(to); } newType(symbol, to); @@ -1646,40 +1641,105 @@ final class Attr extends NodeOperatorVisitor { return !node.isLazy(); } - /** - * Eg. - * - * var d = 17; - * var e; - * e = d; //initially typed as int for node type, should retype as double - * e = object; - * - * var d = 17; - * var e; - * e -= d; //initially type number, should number remain with a final conversion supplied by Store. ugly, but the computation result of the sub is numeric - * e = object; - * - */ + // + // Eg. + // + // var d = 17; + // var e; + // e = d; //initially typed as int for node type, should retype as double + // e = object; + // + // var d = 17; + // var e; + // e -= d; //initially type number, should number remain with a final conversion supplied by Store. ugly, but the computation result of the sub is numeric + // e = object; + // @SuppressWarnings("fallthrough") @Override public Node leaveBinaryNode(final BinaryNode binaryNode) { final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()); BinaryNode newBinaryNode = binaryNode; - switch (binaryNode.tokenType()) { - default: - if (!binaryNode.isAssignment() || binaryNode.isSelfModifying()) { + + if (isAdd(binaryNode)) { + newBinaryNode = (BinaryNode)widen(newBinaryNode, widest); + if (newBinaryNode.getType().isObject() && !isAddString(newBinaryNode)) { + return new RuntimeNode(newBinaryNode, Request.ADD); + } + } else if (binaryNode.isComparison()) { + final Expression lhs = newBinaryNode.lhs(); + final Expression rhs = newBinaryNode.rhs(); + + Type cmpWidest = Type.widest(lhs.getType(), rhs.getType()); + + boolean newRuntimeNode = false, finalized = false; + switch (newBinaryNode.tokenType()) { + case EQ_STRICT: + case NE_STRICT: + if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) { + newRuntimeNode = true; + cmpWidest = Type.OBJECT; + finalized = true; + } + //fallthru + default: + if (newRuntimeNode || cmpWidest.isObject()) { + return new RuntimeNode(newBinaryNode, Request.requestFor(binaryNode)).setIsFinal(finalized); + } break; } + + return newBinaryNode; + } else { + if (!binaryNode.isAssignment() || binaryNode.isSelfModifying()) { + return newBinaryNode; + } + checkThisAssignment(binaryNode); newBinaryNode = newBinaryNode.setLHS(widen(newBinaryNode.lhs(), widest)); - case ADD: newBinaryNode = (BinaryNode)widen(newBinaryNode, widest); } + return newBinaryNode; + + } + + private boolean isAdd(final Node node) { + return node.isTokenType(TokenType.ADD); + } + + /** + * Determine if the outcome of + operator is a string. + * + * @param node Node to test. + * @return true if a string result. + */ + private boolean isAddString(final Node node) { + if (node instanceof BinaryNode && isAdd(node)) { + final BinaryNode binaryNode = (BinaryNode)node; + final Node lhs = binaryNode.lhs(); + final Node rhs = binaryNode.rhs(); + + return isAddString(lhs) || isAddString(rhs); + } + + return node instanceof LiteralNode && ((LiteralNode)node).isString(); + } + + private void checkThisAssignment(final BinaryNode binaryNode) { + if (binaryNode.isAssignment()) { + if (binaryNode.lhs() instanceof AccessNode) { + final AccessNode accessNode = (AccessNode) binaryNode.lhs(); + + if (accessNode.getBase().getSymbol().isThis()) { + lc.getCurrentFunction().addThisProperty(accessNode.getProperty().getName()); + } + } + } } }); lc.replace(currentFunctionNode, newFunctionNode); currentFunctionNode = newFunctionNode; } while (!changed.isEmpty()); + return currentFunctionNode; } @@ -1692,7 +1752,6 @@ final class Attr extends NodeOperatorVisitor { final Expression lhs = binaryNode.lhs(); newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType -// ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine return end(ensureSymbol(destType, binaryNode)); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java index 02ea95f17e6..5eb761e970c 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java @@ -56,10 +56,6 @@ final class BranchOptimizer { branchOptimizer(node, label, state); } - private void load(final Expression node) { - codegen.load(node); - } - private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) { final Expression rhs = unaryNode.rhs(); @@ -67,18 +63,16 @@ final class BranchOptimizer { case NOT: branchOptimizer(rhs, label, !state); return; - case CONVERT: + default: if (unaryNode.getType().isBoolean()) { branchOptimizer(rhs, label, state); return; } break; - default: - break; } // convert to boolean - load(unaryNode); + codegen.load(unaryNode); method.convert(Type.BOOLEAN); if (state) { method.ifne(label); @@ -90,6 +84,7 @@ final class BranchOptimizer { private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) { final Expression lhs = binaryNode.lhs(); final Expression rhs = binaryNode.rhs(); + Type widest = Type.widest(lhs.getType(), rhs.getType()); switch (binaryNode.tokenType()) { case AND: @@ -118,45 +113,33 @@ final class BranchOptimizer { case EQ: case EQ_STRICT: - assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); - load(lhs); - load(rhs); + codegen.loadBinaryOperands(lhs, rhs, widest); method.conditionalJump(state ? EQ : NE, true, label); return; case NE: case NE_STRICT: - assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); - load(lhs); - load(rhs); + codegen.loadBinaryOperands(lhs, rhs, widest); method.conditionalJump(state ? NE : EQ, true, label); return; case GE: - assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); - load(lhs); - load(rhs); + codegen.loadBinaryOperands(lhs, rhs, widest); method.conditionalJump(state ? GE : LT, !state, label); return; case GT: - assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); - load(lhs); - load(rhs); + codegen.loadBinaryOperands(lhs, rhs, widest); method.conditionalJump(state ? GT : LE, !state, label); return; case LE: - assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); - load(lhs); - load(rhs); + codegen.loadBinaryOperands(lhs, rhs, widest); method.conditionalJump(state ? LE : GT, state, label); return; case LT: - assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol() + " in " + binaryNode; - load(lhs); - load(rhs); + codegen.loadBinaryOperands(lhs, rhs, widest); method.conditionalJump(state ? LT : GE, state, label); return; @@ -164,7 +147,7 @@ final class BranchOptimizer { break; } - load(binaryNode); + codegen.load(binaryNode); method.convert(Type.BOOLEAN); if (state) { method.ifne(label); @@ -187,7 +170,7 @@ final class BranchOptimizer { } } - load(node); + codegen.load(node); method.convert(Type.BOOLEAN); if (state) { method.ifne(label); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 8ce908d8197..5575c23db01 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -43,7 +43,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; -import static jdk.nashorn.internal.codegen.CompilerConstants.staticField; import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; @@ -60,7 +59,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Locale; import java.util.Set; import java.util.TreeMap; import jdk.nashorn.internal.codegen.ClassEmitter.Flag; @@ -111,7 +109,6 @@ import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.WhileNode; import jdk.nashorn.internal.ir.WithNode; -import jdk.nashorn.internal.ir.debug.ASTWriter; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.objects.Global; @@ -217,12 +214,12 @@ final class CodeGenerator extends NodeOperatorVisitor SharedScopeCall.FAST_SCOPE_GET_THRESHOLD) { - return loadSharedScopeVar(identNode.getType(), symbol, flags); + return loadSharedScopeVar(type, symbol, flags); } - return loadFastScopeVar(identNode.getType(), symbol, flags, identNode.isFunction()); + return loadFastScopeVar(type, symbol, flags, identNode.isFunction()); } - return method.dynamicGet(identNode.getType(), identNode.getName(), flags, identNode.isFunction()); + return method.dynamicGet(type, identNode.getName(), flags, identNode.isFunction()); } } @@ -313,9 +310,9 @@ final class CodeGenerator extends NodeOperatorVisitor(new LexicalContext()) { + node.accept(new NodeVisitor(lc) { @Override public boolean enterIdentNode(final IdentNode identNode) { - loadIdent(identNode); + loadIdent(identNode, type); return false; } @@ -391,7 +435,7 @@ final class CodeGenerator extends NodeOperatorVisitor literalNode) { + return codegen.enterLiteralNode(literalNode, type); + } + @Override public boolean enterDefault(final Node otherNode) { + final Node currentDiscard = codegen.lc.getCurrentDiscard(); otherNode.accept(codegen); // generate code for whatever we are looking at. - method.load(symbol); // load the final symbol to the stack (or nop if no slot, then result is already there) + if(currentDiscard != otherNode) { + method.load(symbol); // load the final symbol to the stack (or nop if no slot, then result is already there) + assert method.peekType() != null; + method.convert(type); + } return false; } }); @@ -583,15 +643,19 @@ final class CodeGenerator extends NodeOperatorVisitor args = callNode.getArgs(); final Expression function = callNode.getFunction(); final Block currentBlock = lc.getCurrentBlock(); final CodeGeneratorLexicalContext codegenLexicalContext = lc; - final Type callNodeType = callNode.getType(); function.accept(new NodeVisitor(new LexicalContext()) { @@ -612,16 +676,14 @@ final class CodeGenerator extends NodeOperatorVisitor node) { + private MethodEmitter loadLiteral(final LiteralNode node, final Type type) { final Object value = node.getValue(); if (value == null) { @@ -1294,15 +1348,26 @@ final class CodeGenerator extends NodeOperatorVisitor literalNode) { + return enterLiteralNode(literalNode, literalNode.getType()); + } + + private boolean enterLiteralNode(final LiteralNode literalNode, final Type type) { assert literalNode.getSymbol() != null : literalNode + " has no symbol"; - load(literalNode).store(literalNode.getSymbol()); + loadLiteral(literalNode, type).convert(type).store(literalNode.getSymbol()); return false; } @@ -1622,10 +1691,8 @@ final class CodeGenerator extends NodeOperatorVisitor literalNode = (LiteralNode)rhs; - final Object value = literalNode.getValue(); - - if (value instanceof Number) { - assert !to.isArray() : "type hygiene - cannot convert number to array: (" + to.getTypeClass().getSimpleName() + ')' + value; - if (value instanceof Integer) { - method.load((Integer)value); - } else if (value instanceof Long) { - method.load((Long)value); - } else if (value instanceof Double) { - method.load((Double)value); - } else { - assert false; - } - method.convert(Type.OBJECT); - } else if (value instanceof Boolean) { - method.getField(staticField(Boolean.class, value.toString().toUpperCase(Locale.ENGLISH), Boolean.class)); - } else { - load(rhs); - method.convert(unaryNode.getType()); - } - } else { - load(rhs); - method.convert(unaryNode.getType()); - } - - method.store(unaryNode.getSymbol()); - + load(unaryNode.rhs(), Type.INT).load(-1).xor().store(unaryNode.getSymbol()); return false; } @@ -2276,9 +2292,7 @@ final class CodeGenerator extends NodeOperatorVisitor(binaryNode, lhs) { @Override protected void evaluate() { - load(rhs); + if ((lhs instanceof IdentNode) && !lhs.getSymbol().isScope()) { + load(rhs, lhsType); + } else { + load(rhs); + } } }.store(); @@ -2484,8 +2497,7 @@ final class CodeGenerator extends NodeOperatorVisitor(new LexicalContext()) { @Override protected boolean enterDefault(Node node) { throw new AssertionError("Unexpected node " + node + " in store epilogue"); } - @Override - public boolean enterUnaryNode(final UnaryNode node) { - if (node.tokenType() == TokenType.CONVERT && node.getSymbol() != null) { - method.convert(node.rhs().getType()); - } - return true; - } - @Override public boolean enterIdentNode(final IdentNode node) { final Symbol symbol = node.getSymbol(); assert symbol != null; if (symbol.isScope()) { if (isFastScope(symbol)) { - storeFastScopeVar(node.getType(), symbol, CALLSITE_SCOPE | getCallSiteFlags()); + storeFastScopeVar(symbol, CALLSITE_SCOPE | getCallSiteFlags()); } else { - method.dynamicSet(node.getType(), node.getName(), CALLSITE_SCOPE | getCallSiteFlags()); + method.dynamicSet(node.getName(), CALLSITE_SCOPE | getCallSiteFlags()); } } else { + method.convert(node.getType()); method.store(symbol); } return false; @@ -3171,7 +3171,7 @@ final class CodeGenerator extends NodeOperatorVisitor { /** Current class name */ private final String className; @@ -116,4 +116,9 @@ public class CompileUnit { public String toString() { return "[classname=" + className + " weight=" + weight + '/' + Splitter.SPLIT_THRESHOLD + ']'; } + + @Override + public int compareTo(CompileUnit o) { + return className.compareTo(o.className); + } } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java index a31358f6503..24173c3e710 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java @@ -36,8 +36,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE; import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS; -import jdk.nashorn.internal.ir.TemporarySymbols; - import java.io.File; import java.lang.reflect.Field; import java.security.AccessController; @@ -48,18 +46,20 @@ import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; import jdk.internal.dynalink.support.NameCodec; import jdk.nashorn.internal.codegen.ClassEmitter.Flag; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; +import jdk.nashorn.internal.ir.TemporarySymbols; import jdk.nashorn.internal.ir.debug.ClassHistogramElement; import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator; import jdk.nashorn.internal.runtime.CodeInstaller; @@ -256,8 +256,8 @@ public final class Compiler { this.sequence = sequence; this.installer = installer; this.constantData = new ConstantData(); - this.compileUnits = new HashSet<>(); - this.bytecode = new HashMap<>(); + this.compileUnits = new TreeSet<>(); + this.bytecode = new LinkedHashMap<>(); } private void initCompiler(final FunctionNode functionNode) { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java index 63c1fdb79e7..15341484fd7 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java @@ -28,49 +28,22 @@ package jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.Assignment; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.CallNode; -import jdk.nashorn.internal.ir.CaseNode; -import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.ExpressionStatement; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.IfNode; -import jdk.nashorn.internal.ir.IndexNode; import jdk.nashorn.internal.ir.LexicalContext; -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ReturnNode; -import jdk.nashorn.internal.ir.RuntimeNode; -import jdk.nashorn.internal.ir.RuntimeNode.Request; -import jdk.nashorn.internal.ir.SwitchNode; import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.ir.TemporarySymbols; -import jdk.nashorn.internal.ir.TernaryNode; -import jdk.nashorn.internal.ir.ThrowNode; -import jdk.nashorn.internal.ir.TypeOverride; import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.ir.VarNode; -import jdk.nashorn.internal.ir.WhileNode; -import jdk.nashorn.internal.ir.WithNode; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; -import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.parser.TokenType; -import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.DebugLogger; -import jdk.nashorn.internal.runtime.JSType; /** * Lower to more primitive operations. After lowering, an AST has symbols and @@ -97,272 +70,32 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leaveCallNode(final CallNode callNode) { - // AccessSpecializer - call return type may change the access for this location - final Node function = callNode.getFunction(); - if (function instanceof FunctionNode) { - return setTypeOverride(callNode, ((FunctionNode)function).getReturnType()); - } - return callNode; - } - - private Node leaveUnary(final UnaryNode unaryNode) { - return unaryNode.setRHS(convert(unaryNode.rhs(), unaryNode.getType())); - } - - @Override - public Node leaveADD(final UnaryNode unaryNode) { - return leaveUnary(unaryNode); - } - - @Override - public Node leaveBIT_NOT(final UnaryNode unaryNode) { - return leaveUnary(unaryNode); - } - - @Override - public Node leaveCONVERT(final UnaryNode unaryNode) { - assert unaryNode.rhs().tokenType() != TokenType.CONVERT : "convert(convert encountered. check its origin and remove it"; - return unaryNode; - } - - @Override - public Node leaveDECINC(final UnaryNode unaryNode) { - return specialize(unaryNode).node; - } - - @Override - public Node leaveNEW(final UnaryNode unaryNode) { - assert unaryNode.getSymbol() != null && unaryNode.getSymbol().getSymbolType().isObject(); - return unaryNode.setRHS(((CallNode)unaryNode.rhs()).setIsNew()); - } - - @Override - public Node leaveSUB(final UnaryNode unaryNode) { - return leaveUnary(unaryNode); - } - - /** - * Add is a special binary, as it works not only on arithmetic, but for - * strings etc as well. - */ - @Override - public Expression leaveADD(final BinaryNode binaryNode) { - final Expression lhs = binaryNode.lhs(); - final Expression rhs = binaryNode.rhs(); - - final Type type = binaryNode.getType(); - - if (type.isObject()) { - if (!isAddString(binaryNode)) { - return new RuntimeNode(binaryNode, Request.ADD); - } + public Node leaveForNode(final ForNode forNode) { + if (forNode.isForIn()) { + return forNode; } - return binaryNode.setLHS(convert(lhs, type)).setRHS(convert(rhs, type)); - } + final Expression init = forNode.getInit(); + final Expression test = forNode.getTest(); + final Expression modify = forNode.getModify(); - @Override - public Node leaveAND(final BinaryNode binaryNode) { - return binaryNode; - } + assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + lc.getCurrentFunction(); - @Override - public Node leaveASSIGN(final BinaryNode binaryNode) { - final SpecializedNode specialized = specialize(binaryNode); - final BinaryNode specBinaryNode = (BinaryNode)specialized.node; - Type destType = specialized.type; - if (destType == null) { - destType = specBinaryNode.getType(); - } - // Register assignments to this object in case this is used as constructor - if (binaryNode.lhs() instanceof AccessNode) { - AccessNode accessNode = (AccessNode) binaryNode.lhs(); - - if (accessNode.getBase().getSymbol().isThis()) { - lc.getCurrentFunction().addThisProperty(accessNode.getProperty().getName()); - } - } - return specBinaryNode.setRHS(convert(specBinaryNode.rhs(), destType)); - } - - @Override - public Node leaveASSIGN_ADD(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_DIV(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_MOD(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_MUL(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_SAR(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_SHL(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_SHR(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - @Override - public Node leaveASSIGN_SUB(final BinaryNode binaryNode) { - return leaveASSIGN(binaryNode); - } - - private boolean symbolIsInteger(final Expression node) { - final Symbol symbol = node.getSymbol(); - assert symbol != null && symbol.getSymbolType().isInteger() : "int coercion expected: " + Debug.id(symbol) + " " + symbol + " " + lc.getCurrentFunction().getSource(); - return true; - } - - @Override - public Node leaveBIT_AND(final BinaryNode binaryNode) { - assert symbolIsInteger(binaryNode); - return leaveBinary(binaryNode, Type.INT, Type.INT); - } - - @Override - public Node leaveBIT_OR(final BinaryNode binaryNode) { - assert symbolIsInteger(binaryNode); - return leaveBinary(binaryNode, Type.INT, Type.INT); - } - - @Override - public Node leaveBIT_XOR(final BinaryNode binaryNode) { - assert symbolIsInteger(binaryNode); - return leaveBinary(binaryNode, Type.INT, Type.INT); + return forNode. + setInit(lc, init == null ? null : discard(init)). + setModify(lc, modify == null ? null : discard(modify)); } @Override public Node leaveCOMMALEFT(final BinaryNode binaryNode) { assert binaryNode.getSymbol() != null; - final BinaryNode newBinaryNode = binaryNode.setRHS(discard(binaryNode.rhs())); - // AccessSpecializer - the type of lhs, which is the remaining value of this node may have changed - // in that case, update the node type as well - return propagateType(newBinaryNode, newBinaryNode.lhs().getType()); + return binaryNode.setRHS(discard(binaryNode.rhs())); } @Override public Node leaveCOMMARIGHT(final BinaryNode binaryNode) { assert binaryNode.getSymbol() != null; - final BinaryNode newBinaryNode = binaryNode.setLHS(discard(binaryNode.lhs())); - // AccessSpecializer - the type of rhs, which is the remaining value of this node may have changed - // in that case, update the node type as well - return propagateType(newBinaryNode, newBinaryNode.rhs().getType()); - } - - @Override - public Node leaveDIV(final BinaryNode binaryNode) { - return leaveBinaryArith(binaryNode); - } - - - @Override - public Node leaveEQ(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.EQ); - } - - @Override - public Node leaveEQ_STRICT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.EQ_STRICT); - } - - @Override - public Node leaveGE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.GE); - } - - @Override - public Node leaveGT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.GT); - } - - @Override - public Node leaveLE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.LE); - } - - @Override - public Node leaveLT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.LT); - } - - @Override - public Node leaveMOD(final BinaryNode binaryNode) { - return leaveBinaryArith(binaryNode); - } - - @Override - public Node leaveMUL(final BinaryNode binaryNode) { - return leaveBinaryArith(binaryNode); - } - - @Override - public Node leaveNE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.NE); - } - - @Override - public Node leaveNE_STRICT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.NE_STRICT); - } - - @Override - public Node leaveOR(final BinaryNode binaryNode) { - return binaryNode; - } - - @Override - public Node leaveSAR(final BinaryNode binaryNode) { - return leaveBinary(binaryNode, Type.INT, Type.INT); - } - - @Override - public Node leaveSHL(final BinaryNode binaryNode) { - return leaveBinary(binaryNode, Type.INT, Type.INT); - } - - @Override - public Node leaveSHR(final BinaryNode binaryNode) { - assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isLong() : "long coercion expected: " + binaryNode.getSymbol(); - return leaveBinary(binaryNode, Type.INT, Type.INT); - } - - @Override - public Node leaveSUB(final BinaryNode binaryNode) { - return leaveBinaryArith(binaryNode); + return binaryNode.setLHS(discard(binaryNode.lhs())); } @Override @@ -371,38 +104,12 @@ final class FinalizeTypes extends NodeOperatorVisitor { return true; } - @Override - public Node leaveCatchNode(final CatchNode catchNode) { - final Expression exceptionCondition = catchNode.getExceptionCondition(); - if (exceptionCondition != null) { - return catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN)); - } - return catchNode; - } - @Override public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) { temporarySymbols.reuse(); return expressionStatement.setExpression(discard(expressionStatement.getExpression())); } - @Override - public Node leaveForNode(final ForNode forNode) { - final Expression init = forNode.getInit(); - final Expression test = forNode.getTest(); - final Expression modify = forNode.getModify(); - - if (forNode.isForIn()) { - return forNode.setModify(lc, convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400 - } - assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + lc.getCurrentFunction(); - - return forNode. - setInit(lc, init == null ? null : discard(init)). - setTest(lc, test == null ? null : convert(test, Type.BOOLEAN)). - setModify(lc, modify == null ? null : discard(modify)); - } - @Override public boolean enterFunctionNode(final FunctionNode functionNode) { if (functionNode.isLazy()) { @@ -430,113 +137,6 @@ final class FinalizeTypes extends NodeOperatorVisitor { return functionNode.setState(lc, CompilationState.FINALIZED); } - @Override - public Node leaveIfNode(final IfNode ifNode) { - return ifNode.setTest(convert(ifNode.getTest(), Type.BOOLEAN)); - } - - @SuppressWarnings("rawtypes") - @Override - public boolean enterLiteralNode(final LiteralNode literalNode) { - if (literalNode instanceof ArrayLiteralNode) { - final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; - final Expression[] array = arrayLiteralNode.getValue(); - final Type elementType = arrayLiteralNode.getElementType(); - - for (int i = 0; i < array.length; i++) { - final Node element = array[i]; - if (element != null) { - array[i] = convert((Expression)element.accept(this), elementType); - } - } - } - - return false; - } - - @Override - public Node leaveReturnNode(final ReturnNode returnNode) { - final Expression expr = returnNode.getExpression(); - if (expr != null) { - return returnNode.setExpression(convert(expr, lc.getCurrentFunction().getReturnType())); - } - return returnNode; - } - - @Override - public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { - final List args = runtimeNode.getArgs(); - for (final Expression arg : args) { - assert !arg.getType().isUnknown(); - } - return runtimeNode; - } - - @Override - public Node leaveSwitchNode(final SwitchNode switchNode) { - final boolean allInteger = switchNode.getTag().getSymbolType().isInteger(); - - if (allInteger) { - return switchNode; - } - - final Expression expression = switchNode.getExpression(); - final List cases = switchNode.getCases(); - final List newCases = new ArrayList<>(); - - for (final CaseNode caseNode : cases) { - final Expression test = caseNode.getTest(); - newCases.add(test != null ? caseNode.setTest(convert(test, Type.OBJECT)) : caseNode); - } - - return switchNode. - setExpression(lc, convert(expression, Type.OBJECT)). - setCases(lc, newCases); - } - - @Override - public Node leaveTernaryNode(final TernaryNode ternaryNode) { - return ternaryNode.setTest(convert(ternaryNode.getTest(), Type.BOOLEAN)); - } - - @Override - public Node leaveThrowNode(final ThrowNode throwNode) { - return throwNode.setExpression(convert(throwNode.getExpression(), Type.OBJECT)); - } - - @Override - public Node leaveVarNode(final VarNode varNode) { - final Expression init = varNode.getInit(); - if (init != null) { - final SpecializedNode specialized = specialize(varNode); - final VarNode specVarNode = (VarNode)specialized.node; - Type destType = specialized.type; - if (destType == null) { - destType = specVarNode.getName().getType(); - } - assert specVarNode.getName().hasType() : specVarNode + " doesn't have a type"; - final Expression convertedInit = convert(init, destType); - temporarySymbols.reuse(); - return specVarNode.setInit(convertedInit); - } - temporarySymbols.reuse(); - return varNode; - } - - @Override - public Node leaveWhileNode(final WhileNode whileNode) { - final Expression test = whileNode.getTest(); - if (test != null) { - return whileNode.setTest(lc, convert(test, Type.BOOLEAN)); - } - return whileNode; - } - - @Override - public Node leaveWithNode(final WithNode withNode) { - return withNode.setExpression(lc, convert(withNode.getExpression(), Type.OBJECT)); - } - private static void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) { if (LOG.isEnabled()) { if (!symbol.isScope()) { @@ -583,260 +183,6 @@ final class FinalizeTypes extends NodeOperatorVisitor { } } - /** - * Exit a comparison node and do the appropriate replacements. We need to introduce runtime - * nodes late for comparisons as types aren't known until the last minute - * - * Both compares and adds may turn into runtimes node at this level as when we first bump - * into the op in Attr, we may type it according to what we know there, which may be wrong later - * - * e.g. i (int) < 5 -> normal compare - * i = object - * then the post pass that would add the conversion to the 5 needs to - * - * @param binaryNode binary node to leave - * @param request runtime request - * @return lowered cmp node - */ - @SuppressWarnings("fallthrough") - private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) { - final Expression lhs = binaryNode.lhs(); - final Expression rhs = binaryNode.rhs(); - - Type widest = Type.widest(lhs.getType(), rhs.getType()); - - boolean newRuntimeNode = false, finalized = false; - switch (request) { - case EQ_STRICT: - case NE_STRICT: - if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) { - newRuntimeNode = true; - widest = Type.OBJECT; - finalized = true; - } - //fallthru - default: - if (newRuntimeNode || widest.isObject()) { - return new RuntimeNode(binaryNode, request).setIsFinal(finalized); - } - break; - } - - return binaryNode.setLHS(convert(lhs, widest)).setRHS(convert(rhs, widest)); - } - - /** - * Compute the binary arithmetic type given the lhs and an rhs of a binary expression - * @param lhsType the lhs type - * @param rhsType the rhs type - * @return the correct binary type - */ - private static Type binaryArithType(final Type lhsType, final Type rhsType) { - if (!Compiler.shouldUseIntegerArithmetic()) { - return Type.NUMBER; - } - return Type.widest(lhsType, rhsType, Type.NUMBER); - } - - private Node leaveBinaryArith(final BinaryNode binaryNode) { - final Type type = binaryArithType(binaryNode.lhs().getType(), binaryNode.rhs().getType()); - return leaveBinary(binaryNode, type, type); - } - - private Node leaveBinary(final BinaryNode binaryNode, final Type lhsType, final Type rhsType) { - Node b = binaryNode.setLHS(convert(binaryNode.lhs(), lhsType)).setRHS(convert(binaryNode.rhs(), rhsType)); - return b; - } - - /** - * A symbol (and {@link jdk.nashorn.internal.runtime.Property}) can be tagged as "may be primitive". - * This is used a hint for dual fields that it is even worth it to try representing this - * field as something other than java.lang.Object. - * - * @param node node in which to tag symbols as primitive - * @param to which primitive type to use for tagging - */ - private static void setCanBePrimitive(final Node node, final Type to) { - final HashSet exclude = new HashSet<>(); - - node.accept(new NodeVisitor(new LexicalContext()) { - private void setCanBePrimitive(final Symbol symbol) { - LOG.info("*** can be primitive symbol ", symbol, " ", Debug.id(symbol)); - symbol.setCanBePrimitive(to); - } - - @Override - public boolean enterIdentNode(final IdentNode identNode) { - if (!exclude.contains(identNode)) { - setCanBePrimitive(identNode.getSymbol()); - } - return false; - } - - @Override - public boolean enterAccessNode(final AccessNode accessNode) { - setCanBePrimitive(accessNode.getProperty().getSymbol()); - return false; - } - - @Override - public boolean enterIndexNode(final IndexNode indexNode) { - exclude.add(indexNode.getBase()); //prevent array base node to be flagged as primitive, but k in a[k++] is fine - return true; - } - }); - } - - private static class SpecializedNode { - final Node node; - final Type type; - - SpecializedNode(Node node, Type type) { - this.node = node; - this.type = type; - } - } - - SpecializedNode specialize(final Assignment assignment) { - final Node node = ((Node)assignment); - final T lhs = assignment.getAssignmentDest(); - final Expression rhs = assignment.getAssignmentSource(); - - if (!canHaveCallSiteType(lhs)) { - return new SpecializedNode(node, null); - } - - final Type to; - if (node.isSelfModifying()) { - to = node.getWidestOperationType(); - } else { - to = rhs.getType(); - } - - if (!isSupportedCallSiteType(to)) { - //meaningless to specialize to boolean or object - return new SpecializedNode(node, null); - } - - final Node newNode = assignment.setAssignmentDest(setTypeOverride(lhs, to)); - final Node typePropagatedNode; - if(newNode instanceof Expression) { - typePropagatedNode = propagateType((Expression)newNode, to); - } else if(newNode instanceof VarNode) { - // VarNode, being a statement, doesn't have its own symbol; it uses the symbol of its name instead. - final VarNode varNode = (VarNode)newNode; - typePropagatedNode = varNode.setName((IdentNode)propagateType(varNode.getName(), to)); - } else { - throw new AssertionError(); - } - return new SpecializedNode(typePropagatedNode, to); - } - - - /** - * Is this a node that can have its type overridden. This is true for - * AccessNodes, IndexNodes and IdentNodes - * - * @param node the node to check - * @return true if node can have a callsite type - */ - private static boolean canHaveCallSiteType(final Node node) { - return node instanceof TypeOverride && ((TypeOverride)node).canHaveCallSiteType(); - } - - /** - * Is the specialization type supported. Currently we treat booleans as objects - * and have no special boolean type accessor, thus booleans are ignored. - * TODO - support booleans? NASHORN-590 - * - * @param castTo the type to check - * @return true if call site type is supported - */ - private static boolean isSupportedCallSiteType(final Type castTo) { - return castTo.isNumeric(); // don't specializable for boolean - } - - /** - * Override the type of a node for e.g. access specialization of scope - * objects. Normally a variable can only get a wider type and narrower type - * sets are ignored. Not that a variable can still be on object type as - * per the type analysis, but a specific access may be narrower, e.g. if it - * is used in an arithmetic op. This overrides a type, regardless of - * type environment and is used primarily by the access specializer - * - * @param node node for which to change type - * @param to new type - */ - @SuppressWarnings("unchecked") - T setTypeOverride(final T node, final Type to) { - final Type from = node.getType(); - if (!node.getType().equals(to)) { - LOG.info("Changing call override type for '", node, "' from ", node.getType(), " to ", to); - if (!to.isObject() && from.isObject()) { - setCanBePrimitive(node, to); - } - } - LOG.info("Type override for lhs in '", node, "' => ", to); - return ((TypeOverride)node).setType(temporarySymbols, lc, to); - } - - /** - * Add an explicit conversion. This is needed when attribution has created types - * that do not mesh into an op type, e.g. a = b, where b is object and a is double - * at the end of Attr, needs explicit conversion logic. - * - * An explicit conversion can be one of the following: - * + Convert a literal - just replace it with another literal - * + Convert a scope object - just replace the type of the access, e.g. get()D->get()I - * + Explicit convert placement, e.g. a = (double)b - all other cases - * - * No other part of the world after {@link Attr} may introduce new symbols. This - * is the only place. - * - * @param node node to convert - * @param to destination type - * @return conversion node - */ - private Expression convert(final Expression node, final Type to) { - assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass(); - assert node != null : "node is null"; - assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + lc.getCurrentFunction(); - assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + lc.getCurrentFunction(); - - final Type from = node.getType(); - - if (Type.areEquivalent(from, to)) { - return node; - } - - if (from.isObject() && to.isObject()) { - return node; - } - - Expression resultNode = node; - - if (node instanceof LiteralNode && !(node instanceof ArrayLiteralNode) && !to.isObject()) { - final LiteralNode newNode = new LiteralNodeConstantEvaluator((LiteralNode)node, to).eval(); - if (newNode != null) { - resultNode = newNode; - } - } else { - if (canHaveCallSiteType(node) && isSupportedCallSiteType(to)) { - assert node instanceof TypeOverride; - return setTypeOverride(node, to); - } - resultNode = new UnaryNode(Token.recast(node.getToken(), TokenType.CONVERT), node); - } - - LOG.info("CONVERT('", node, "', ", to, ") => '", resultNode, "'"); - - assert !node.isTerminal(); - - //This is the only place in this file that can create new temporaries - //FinalizeTypes may not introduce ANY node that is not a conversion. - return temporarySymbols.ensureSymbol(lc, to, resultNode); - } - private static Expression discard(final Expression node) { if (node.getSymbol() != null) { final UnaryNode discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node); @@ -849,82 +195,5 @@ final class FinalizeTypes extends NodeOperatorVisitor { return node; } - /** - * Whenever an expression like an addition or an assignment changes type, it - * may be that case that {@link Attr} created a symbol for an intermediate - * result of the expression, say for an addition. This also has to be updated - * if the expression type changes. - * - * Assignments use their lhs as node symbol, and in this case we can't modify - * it. Then {@link CodeGenerator.Store} needs to do an explicit conversion. - * This is happens very rarely. - * - * @param node - * @param to - */ - private Expression propagateType(final Expression node, final Type to) { - Symbol symbol = node.getSymbol(); - if (symbol.isTemp() && symbol.getSymbolType() != to) { - symbol = symbol.setTypeOverrideShared(to, temporarySymbols); - LOG.info("Type override for temporary in '", node, "' => ", to); - } - return node.setSymbol(lc, symbol); - } - /** - * Determine if the outcome of + operator is a string. - * - * @param node Node to test. - * @return true if a string result. - */ - private boolean isAddString(final Node node) { - if (node instanceof BinaryNode && node.isTokenType(TokenType.ADD)) { - final BinaryNode binaryNode = (BinaryNode)node; - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); - - return isAddString(lhs) || isAddString(rhs); - } - - return node instanceof LiteralNode && ((LiteralNode)node).isString(); - } - - /** - * Whenever an explicit conversion is needed and the convertee is a literal, we can - * just change the literal - */ - class LiteralNodeConstantEvaluator extends FoldConstants.ConstantEvaluator> { - private final Type type; - - LiteralNodeConstantEvaluator(final LiteralNode parent, final Type type) { - super(parent); - this.type = type; - } - - @Override - protected LiteralNode eval() { - final Object value = ((LiteralNode)parent).getValue(); - - LiteralNode literalNode = null; - - if (type.isString()) { - literalNode = LiteralNode.newInstance(token, finish, JSType.toString(value)); - } else if (type.isBoolean()) { - literalNode = LiteralNode.newInstance(token, finish, JSType.toBoolean(value)); - } else if (type.isInteger()) { - literalNode = LiteralNode.newInstance(token, finish, JSType.toInt32(value)); - } else if (type.isLong()) { - literalNode = LiteralNode.newInstance(token, finish, JSType.toLong(value)); - } else if (type.isNumber() || parent.getType().isNumeric() && !parent.getType().isNumber()) { - literalNode = LiteralNode.newInstance(token, finish, JSType.toNumber(value)); - } - - if (literalNode != null) { - //inherit literal symbol for attr. - literalNode = (LiteralNode)literalNode.setSymbol(lc, parent.getSymbol()); - } - - return literalNode; - } - } } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java index 8a012ccbac1..7b452421bcf 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java @@ -69,7 +69,6 @@ import java.io.PrintStream; import java.lang.reflect.Array; import java.util.EnumSet; import java.util.List; - import jdk.internal.dynalink.support.NameCodec; import jdk.internal.org.objectweb.asm.Handle; import jdk.internal.org.objectweb.asm.MethodVisitor; @@ -1560,7 +1559,7 @@ public class MethodEmitter implements Emitter { MethodEmitter convert(final Type to) { final Type type = peekType().convert(method, to); if (type != null) { - if (peekType() != to) { + if (!peekType().isEquivalentTo(to)) { debug("convert", peekType(), "->", to); } popType(); @@ -1790,15 +1789,14 @@ public class MethodEmitter implements Emitter { * @param name name of property * @param flags call site flags */ - void dynamicSet(final Type valueType, final String name, final int flags) { + void dynamicSet(final String name, final int flags) { debug("dynamic_set", name, peekType()); - Type type = valueType; - if (type.isObject() || type.isBoolean()) { //promote strings to objects etc + Type type = peekType(); + if (type.isObject()) { //promote strings to objects etc type = Type.OBJECT; convert(Type.OBJECT); //TODO bad- until we specialize boolean setters, } - popType(type); popType(Type.SCOPE); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java index 9ecfccd6126..f5940488c35 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java @@ -296,11 +296,6 @@ final class WeighNodes extends NodeOperatorVisitor { return unaryNodeWeight(unaryNode); } - @Override - public Node leaveCONVERT(final UnaryNode unaryNode) { - return unaryNodeWeight(unaryNode); - } - @Override public Node leaveDECINC(final UnaryNode unaryNode) { return unaryNodeWeight(unaryNode); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java index 4331cb556c7..840b291070c 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java @@ -136,8 +136,7 @@ public final class BooleanType extends Type { invokeStatic(method, JSType.TO_LONG); } else if (to.isString()) { invokeStatic(method, VALUE_OF); - invokeStatic(method, JSType.TO_PRIMITIVE); - invokeStatic(method, JSType.TO_STRING); + invokeStatic(method, JSType.TO_PRIMITIVE_TO_STRING); } else if (to.isObject()) { invokeStatic(method, VALUE_OF); } else { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java index cb2f876bfc2..1f7a02214a2 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java @@ -153,8 +153,7 @@ class ObjectType extends Type { } else if (to.isBoolean()) { invokeStatic(method, JSType.TO_BOOLEAN); } else if (to.isString()) { - invokeStatic(method, JSType.TO_PRIMITIVE); - invokeStatic(method, JSType.TO_STRING); + invokeStatic(method, JSType.TO_PRIMITIVE_TO_STRING); } else { assert false : "Illegal conversion " + this + " -> " + to + " " + isString() + " " + toString; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java index c1e8bfbb432..2fa2c3152c0 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java @@ -441,7 +441,12 @@ public abstract class Type implements Comparable, BytecodeOps { if (type0.isArray() && type1.isArray()) { return ((ArrayType)type0).getElementType() == ((ArrayType)type1).getElementType() ? type0 : Type.OBJECT; } else if (type0.isArray() != type1.isArray()) { - return Type.OBJECT; //array and non array is always object, widest(Object[], int) NEVER returns Object[], which has most weight. that does not make sense + //array and non array is always object, widest(Object[], int) NEVER returns Object[], which has most weight. that does not make sense + return Type.OBJECT; + } else if (type0.isObject() && type1.isObject() && ((ObjectType)type0).getTypeClass() != ((ObjectType)type1).getTypeClass()) { + // Object and Object will produce Object + // TODO: maybe find most specific common superclass? + return Type.OBJECT; } return type0.weight() > type1.weight() ? type0 : type1; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java index 55b0aa3feb3..957adf696b2 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java @@ -25,7 +25,6 @@ package jdk.nashorn.internal.ir; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -46,12 +45,12 @@ public final class AccessNode extends BaseNode { * @param property property */ public AccessNode(final long token, final int finish, final Expression base, final IdentNode property) { - super(token, finish, base, false, false); + super(token, finish, base, false); this.property = property.setIsPropertyName(); } - private AccessNode(final AccessNode accessNode, final Expression base, final IdentNode property, final boolean isFunction, final boolean hasCallSiteType) { - super(accessNode, base, isFunction, hasCallSiteType); + private AccessNode(final AccessNode accessNode, final Expression base, final IdentNode property, final boolean isFunction) { + super(accessNode, base, isFunction); this.property = property; } @@ -73,13 +72,6 @@ public final class AccessNode extends BaseNode { public void toString(final StringBuilder sb) { final boolean needsParen = tokenType().needsParens(getBase().tokenType(), true); - if (hasCallSiteType()) { - sb.append('{'); - final String desc = getType().getDescriptor(); - sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : getType().getDescriptor()); - sb.append('}'); - } - if (needsParen) { sb.append('('); } @@ -107,21 +99,14 @@ public final class AccessNode extends BaseNode { if (this.base == base) { return this; } - return new AccessNode(this, base, property, isFunction(), hasCallSiteType()); + return new AccessNode(this, base, property, isFunction()); } private AccessNode setProperty(final IdentNode property) { if (this.property == property) { return this; } - return new AccessNode(this, base, property, isFunction(), hasCallSiteType()); - } - - @Override - public AccessNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) { - logTypeChange(type); - final AccessNode newAccessNode = (AccessNode)setSymbol(lc, getSymbol().setTypeOverrideShared(type, ts)); - return new AccessNode(newAccessNode, base, property.setType(ts, lc, type), isFunction(), hasCallSiteType()); + return new AccessNode(this, base, property, isFunction()); } @Override @@ -129,7 +114,7 @@ public final class AccessNode extends BaseNode { if (isFunction()) { return this; } - return new AccessNode(this, base, property, true, hasCallSiteType()); + return new AccessNode(this, base, property, true); } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java index f945ef35711..96f155d1385 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java @@ -25,10 +25,6 @@ package jdk.nashorn.internal.ir; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS; - -import jdk.nashorn.internal.codegen.ObjectClassGenerator; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; /** @@ -38,15 +34,13 @@ import jdk.nashorn.internal.ir.annotations.Immutable; * @see IndexNode */ @Immutable -public abstract class BaseNode extends Expression implements FunctionCall, TypeOverride { +public abstract class BaseNode extends Expression implements FunctionCall { /** Base Node. */ protected final Expression base; private final boolean isFunction; - private final boolean hasCallSiteType; - /** * Constructor * @@ -54,13 +48,11 @@ public abstract class BaseNode extends Expression implements FunctionCall, TypeO * @param finish finish * @param base base node * @param isFunction is this a function - * @param hasCallSiteType does this access have a callsite type */ - public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean hasCallSiteType) { + public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction) { super(token, base.getStart(), finish); this.base = base; this.isFunction = isFunction; - this.hasCallSiteType = hasCallSiteType; } /** @@ -68,13 +60,11 @@ public abstract class BaseNode extends Expression implements FunctionCall, TypeO * @param baseNode node to inherit from * @param base base * @param isFunction is this a function - * @param hasCallSiteType does this access have a callsite type */ - protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final boolean hasCallSiteType) { + protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction) { super(baseNode); this.base = base; this.isFunction = isFunction; - this.hasCallSiteType = hasCallSiteType; } /** @@ -96,26 +86,4 @@ public abstract class BaseNode extends Expression implements FunctionCall, TypeO */ public abstract BaseNode setIsFunction(); - @Override - public boolean canHaveCallSiteType() { - return true; //carried by the symbol and always the same nodetype==symboltype - } - - /** - * Does the access have a call site type override? - * @return true if overridden - */ - protected boolean hasCallSiteType() { - return hasCallSiteType; - } - - /** - * Debug type change - * @param type new type - */ - protected final void logTypeChange(final Type type) { - if (DEBUG_FIELDS && !Type.areEquivalent(getSymbol().getSymbolType(), type)) { - ObjectClassGenerator.LOG.info(getClass().getName(), " ", this, " => ", type, " instead of ", getType()); - } - } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java index ffaae078d78..0d38f241f02 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java @@ -36,9 +36,7 @@ import jdk.nashorn.internal.ir.visitor.NodeVisitor; * IR representation for a function call. */ @Immutable -public final class CallNode extends LexicalContextExpression implements TypeOverride { - - private final Type type; +public final class CallNode extends LexicalContextExpression { /** Function identifier or function body. */ private final Expression function; @@ -150,18 +148,16 @@ public final class CallNode extends LexicalContextExpression implements TypeOver this.function = function; this.args = args; this.flags = 0; - this.type = null; this.evalArgs = null; this.lineNumber = lineNumber; } - private CallNode(final CallNode callNode, final Expression function, final List args, final int flags, final Type type, final EvalArgs evalArgs) { + private CallNode(final CallNode callNode, final Expression function, final List args, final int flags, final EvalArgs evalArgs) { super(callNode); this.lineNumber = callNode.lineNumber; this.function = function; this.args = args; this.flags = flags; - this.type = type; this.evalArgs = evalArgs; } @@ -175,29 +171,9 @@ public final class CallNode extends LexicalContextExpression implements TypeOver @Override public Type getType() { - if (hasCallSiteType()) { - return type; - } return function instanceof FunctionNode ? ((FunctionNode)function).getReturnType() : Type.OBJECT; } - @Override - public CallNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) { - if (this.type == type) { - return this; - } - return new CallNode(this, function, args, flags, type, evalArgs); - } - - private boolean hasCallSiteType() { - return this.type != null; - } - - @Override - public boolean canHaveCallSiteType() { - return true; - } - /** * Assist in IR navigation. * @@ -212,7 +188,6 @@ public final class CallNode extends LexicalContextExpression implements TypeOver setFunction((Expression)function.accept(visitor)). setArgs(Node.accept(visitor, Expression.class, args)). setFlags(flags). - setType(null, lc, type). setEvalArgs(evalArgs == null ? null : evalArgs.setCode((Expression)evalArgs.getCode().accept(visitor)). @@ -229,13 +204,6 @@ public final class CallNode extends LexicalContextExpression implements TypeOver @Override public void toString(final StringBuilder sb) { - if (hasCallSiteType()) { - sb.append('{'); - final String desc = getType().getDescriptor(); - sb.append(desc.charAt(desc.length() - 1) == ';' ? 'O' : getType().getDescriptor()); - sb.append('}'); - } - function.toString(sb); sb.append('('); @@ -271,7 +239,7 @@ public final class CallNode extends LexicalContextExpression implements TypeOver if (this.args == args) { return this; } - return new CallNode(this, function, args, flags, type, evalArgs); + return new CallNode(this, function, args, flags, evalArgs); } /** @@ -293,7 +261,7 @@ public final class CallNode extends LexicalContextExpression implements TypeOver if (this.evalArgs == evalArgs) { return this; } - return new CallNode(this, function, args, flags, type, evalArgs); + return new CallNode(this, function, args, flags, evalArgs); } /** @@ -321,7 +289,7 @@ public final class CallNode extends LexicalContextExpression implements TypeOver if (this.function == function) { return this; } - return new CallNode(this, function, args, flags, type, evalArgs); + return new CallNode(this, function, args, flags, evalArgs); } /** @@ -344,6 +312,6 @@ public final class CallNode extends LexicalContextExpression implements TypeOver if (this.flags == flags) { return this; } - return new CallNode(this, function, args, flags, type, evalArgs); + return new CallNode(this, function, args, flags, evalArgs); } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java index 6060899dfc6..631153b804e 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java @@ -28,9 +28,7 @@ package jdk.nashorn.internal.ir; import static jdk.nashorn.internal.codegen.CompilerConstants.__DIR__; import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__; import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS; -import jdk.nashorn.internal.codegen.ObjectClassGenerator; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -39,7 +37,7 @@ import jdk.nashorn.internal.ir.visitor.NodeVisitor; * IR representation for an identifier. */ @Immutable -public final class IdentNode extends Expression implements PropertyKey, TypeOverride, FunctionCall { +public final class IdentNode extends Expression implements PropertyKey, FunctionCall { private static final int PROPERTY_NAME = 1 << 0; private static final int INITIALIZED_HERE = 1 << 1; private static final int FUNCTION = 1 << 2; @@ -101,19 +99,6 @@ public final class IdentNode extends Expression implements PropertyKey, TypeOver return callSiteType != null; } - @Override - public IdentNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) { - // do NOT, repeat NOT touch the symbol here. it might be a local variable or whatever. This is the override if it isn't - if (this.callSiteType == type) { - return this; - } - if (DEBUG_FIELDS && getSymbol() != null && !Type.areEquivalent(getSymbol().getSymbolType(), type)) { - ObjectClassGenerator.LOG.info(getClass().getName(), " ", this, " => ", type, " instead of ", getType()); - } - - return new IdentNode(this, name, type, flags); - } - /** * Assist in IR navigation. * @@ -153,31 +138,6 @@ public final class IdentNode extends Expression implements PropertyKey, TypeOver return getName(); } - /** - * We can only override type if the symbol lives in the scope, as otherwise - * it is strongly determined by the local variable already allocated. - * - *

    We also return true if the symbol represents the return value of a function with a - * non-generic return type as in this case we need to propagate the type instead of - * converting to object, for example if the symbol is used as the left hand side of an - * assignment such as in the code below.

    - * - *
    -     *   try {
    -     *     return 2;
    -     *   } finally {
    -     *     return 3;
    -     *   }
    -     * }
    -     * 
    - * - * @return true if can have callsite type - */ - @Override - public boolean canHaveCallSiteType() { - return getSymbol() != null && (getSymbol().isScope() || getSymbol().isNonGenericReturn()); - } - /** * Check if this IdentNode is a property name * @return true if this is a property name diff --git a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java index 2799e9bee62..83f58ffcad8 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java @@ -25,7 +25,6 @@ package jdk.nashorn.internal.ir; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -46,12 +45,12 @@ public final class IndexNode extends BaseNode { * @param index index for access */ public IndexNode(final long token, final int finish, final Expression base, final Expression index) { - super(token, finish, base, false, false); + super(token, finish, base, false); this.index = index; } - private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction, final boolean hasCallSiteType) { - super(indexNode, base, isFunction, hasCallSiteType); + private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction) { + super(indexNode, base, isFunction); this.index = index; } @@ -69,13 +68,6 @@ public final class IndexNode extends BaseNode { public void toString(final StringBuilder sb) { final boolean needsParen = tokenType().needsParens(base.tokenType(), true); - if (hasCallSiteType()) { - sb.append('{'); - final String desc = getType().getDescriptor(); - sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : getType().getDescriptor()); - sb.append('}'); - } - if (needsParen) { sb.append('('); } @@ -103,7 +95,7 @@ public final class IndexNode extends BaseNode { if (this.base == base) { return this; } - return new IndexNode(this, base, index, isFunction(), hasCallSiteType()); + return new IndexNode(this, base, index, isFunction()); } /** @@ -115,7 +107,7 @@ public final class IndexNode extends BaseNode { if(this.index == index) { return this; } - return new IndexNode(this, base, index, isFunction(), hasCallSiteType()); + return new IndexNode(this, base, index, isFunction()); } @Override @@ -123,14 +115,7 @@ public final class IndexNode extends BaseNode { if (isFunction()) { return this; } - return new IndexNode(this, base, index, true, hasCallSiteType()); - } - - @Override - public IndexNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) { - logTypeChange(type); - final IndexNode newIndexNode = (IndexNode)setSymbol(lc, getSymbol().setTypeOverrideShared(type, ts)); - return new IndexNode(newIndexNode, base, index, isFunction(), true); + return new IndexNode(this, base, index, true); } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java index 618182c8e42..3d3a1fcbb5d 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java @@ -28,10 +28,13 @@ package jdk.nashorn.internal.ir; import java.util.Arrays; import java.util.Collections; import java.util.List; + import jdk.nashorn.internal.codegen.CompileUnit; +import jdk.nashorn.internal.codegen.types.ArrayType; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.parser.Lexer.LexerToken; import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.parser.TokenType; @@ -526,12 +529,6 @@ public abstract class LiteralNode extends Expression implements PropertyKey { return object; } else if (object instanceof LiteralNode) { return objectAsConstant(((LiteralNode)object).getValue()); - } else if (object instanceof UnaryNode) { - final UnaryNode unaryNode = (UnaryNode)object; - - if (unaryNode.isTokenType(TokenType.CONVERT) && unaryNode.getType().isObject()) { - return objectAsConstant(unaryNode.rhs()); - } } return POSTSET_MARKER; @@ -782,8 +779,7 @@ public abstract class LiteralNode extends Expression implements PropertyKey { return value; } - @Override - public Type getType() { + public ArrayType getArrayType() { if (elementType.isInteger()) { return Type.INT_ARRAY; } else if (elementType.isLong()) { @@ -795,6 +791,11 @@ public abstract class LiteralNode extends Expression implements PropertyKey { } } + @Override + public Type getType() { + return Type.typeFor(NativeArray.class); + } + /** * Get the element type of this array literal * @return element type diff --git a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java index d100b4080ce..269cb9054f4 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java @@ -38,7 +38,7 @@ import jdk.nashorn.internal.parser.TokenType; * IR representation for a runtime call. */ @Immutable -public class RuntimeNode extends Expression implements TypeOverride { +public class RuntimeNode extends Expression { /** * Request enum used for meta-information about the runtime request @@ -158,6 +158,36 @@ public class RuntimeNode extends Expression implements TypeOverride } } + /** + * Derive a runtime node request type for a node + * @param node the node + * @return request type + */ + public static Request requestFor(final Node node) { + assert node.isComparison(); + switch (node.tokenType()) { + case EQ_STRICT: + return Request.EQ_STRICT; + case NE_STRICT: + return Request.NE_STRICT; + case EQ: + return Request.EQ; + case NE: + return Request.NE; + case LT: + return Request.LT; + case LE: + return Request.LE; + case GT: + return Request.GT; + case GE: + return Request.GE; + default: + assert false; + return null; + } + } + /** * Is this an EQ or EQ_STRICT? * @@ -268,9 +298,6 @@ public class RuntimeNode extends Expression implements TypeOverride /** Call arguments. */ private final List args; - /** Call site override - e.g. we know that a ScriptRuntime.ADD will return an int */ - private final Type callSiteType; - /** is final - i.e. may not be removed again, lower in the code pipeline */ private final boolean isFinal; @@ -287,16 +314,14 @@ public class RuntimeNode extends Expression implements TypeOverride this.request = request; this.args = args; - this.callSiteType = null; this.isFinal = false; } - private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final Type callSiteType, final boolean isFinal, final List args) { + private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final boolean isFinal, final List args) { super(runtimeNode); this.request = request; this.args = args; - this.callSiteType = callSiteType; this.isFinal = isFinal; } @@ -335,7 +360,6 @@ public class RuntimeNode extends Expression implements TypeOverride this.request = request; this.args = args; - this.callSiteType = null; this.isFinal = false; } @@ -376,7 +400,7 @@ public class RuntimeNode extends Expression implements TypeOverride if (this.isFinal == isFinal) { return this; } - return new RuntimeNode(this, request, callSiteType, isFinal, args); + return new RuntimeNode(this, request, isFinal, args); } /** @@ -384,24 +408,7 @@ public class RuntimeNode extends Expression implements TypeOverride */ @Override public Type getType() { - return hasCallSiteType() ? callSiteType : request.getReturnType(); - } - - @Override - public RuntimeNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) { - if (this.callSiteType == type) { - return this; - } - return new RuntimeNode(this, request, type, isFinal, args); - } - - @Override - public boolean canHaveCallSiteType() { - return request == Request.ADD; - } - - private boolean hasCallSiteType() { - return callSiteType != null; + return request.getReturnType(); } @Override @@ -450,7 +457,7 @@ public class RuntimeNode extends Expression implements TypeOverride if (this.args == args) { return this; } - return new RuntimeNode(this, request, callSiteType, isFinal, args); + return new RuntimeNode(this, request, isFinal, args); } /** diff --git a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java deleted file mode 100644 index 929d0128e97..00000000000 --- a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.ir; - -import jdk.nashorn.internal.codegen.types.Type; - -/** - * A type override makes it possible to change the return type of a node, if we know - * that the linker can provide it directly. For example, an identity node that is - * in the scope, can very well look like an object to the compiler of the method it - * is in, but if someone does (int)x, it make senses to ask for it directly - * with an int getter instead of loading it as an object and explicitly converting it - * by using JSType.toInt32. Especially in scenarios where the field is already stored - * as a primitive, this will be much faster than the "object is all I see" scope - * available in the method - * @param the type of the node implementing the interface - */ - -public interface TypeOverride { - /** - * Set the override type - * - * @param ts temporary symbols - * @param lc the current lexical context - * @param type the type - * @return a node equivalent to this one except for the requested change. - */ - public T setType(final TemporarySymbols ts, final LexicalContext lc, final Type type); - - /** - * Returns true if this node can have a callsite override, e.g. all scope ident nodes - * which lead to dynamic getters can have it, local variable nodes (slots) can't. - * Call nodes can have it unconditionally and so on - * - * @return true if it is possible to assign a type override to this node - */ - public boolean canHaveCallSiteType(); - -} diff --git a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java index 2de2ca5dee9..3857dd3917e 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java @@ -26,7 +26,6 @@ package jdk.nashorn.internal.ir; import static jdk.nashorn.internal.parser.TokenType.BIT_NOT; -import static jdk.nashorn.internal.parser.TokenType.CONVERT; import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX; import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX; @@ -150,19 +149,10 @@ public final class UnaryNode extends Expression implements Assignment extends NodeVisitor extends NodeVisitor extends NodeVisitor clazz) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - Class bottomClazz = clazz; - while(bottomClazz.isArray()) { + Class bottomClazz = clazz; + while (bottomClazz.isArray()) { bottomClazz = bottomClazz.getComponentType(); } checkPackageAccess(sm, bottomClazz.getName()); @@ -664,7 +664,7 @@ public final class Context { * @param clazz Class object * @return true if package is accessible, false otherwise */ - private static boolean isAccessiblePackage(final Class clazz) { + private static boolean isAccessiblePackage(final Class clazz) { try { checkPackageAccess(clazz); return true; @@ -838,7 +838,7 @@ public final class Context { return Context.getContextTrusted(); } - private URL getResourceURL(final String resName) throws IOException { + private URL getResourceURL(final String resName) { // try the classPathLoader if we have and then // try the appLoader if non-null. if (classPathLoader != null) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index 93f0835b465..8c79caa7fdc 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -104,14 +104,11 @@ public enum JSType { /** JavaScript compliant conversion function from number to int64 */ public static final Call TO_INT64_D = staticCall(myLookup, JSType.class, "toInt64", long.class, double.class); - /** JavaScript compliant conversion function from Object to String */ - public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class); - /** JavaScript compliant conversion function from number to String */ public static final Call TO_STRING_D = staticCall(myLookup, JSType.class, "toString", String.class, double.class); - /** JavaScript compliant conversion function from Object to primitive */ - public static final Call TO_PRIMITIVE = staticCall(myLookup, JSType.class, "toPrimitive", Object.class, Object.class); + /** Combined call to toPrimitive followed by toString. */ + public static final Call TO_PRIMITIVE_TO_STRING = staticCall(myLookup, JSType.class, "toPrimitiveToString", String.class, Object.class); private static final double INT32_LIMIT = 4294967296.0; @@ -272,6 +269,17 @@ public enum JSType { return result; } + /** + * Combines a hintless toPrimitive and a toString call. + * + * @param obj an object + * + * @return the string form of the primitive form of the object + */ + public static String toPrimitiveToString(Object obj) { + return toString(toPrimitive(obj)); + } + /** * JavaScript compliant conversion of number to boolean * @@ -874,7 +882,7 @@ public enum JSType { if (obj instanceof ScriptObject) { return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType); } else if (obj instanceof JSObject) { - final ArrayLikeIterator itr = ArrayLikeIterator.arrayLikeIterator(obj); + final ArrayLikeIterator itr = ArrayLikeIterator.arrayLikeIterator(obj); final int len = (int) itr.getLength(); final Object[] res = new Object[len]; int idx = 0; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/JavaArrayIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JavaArrayIterator.java index 92a80029384..a6b6bb9a4a7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/JavaArrayIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JavaArrayIterator.java @@ -77,4 +77,4 @@ class JavaArrayIterator extends ArrayLikeIterator { public void remove() { throw new UnsupportedOperationException("remove"); } -} \ No newline at end of file +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJavaArrayIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJavaArrayIterator.java index dcb37cfd197..b90bae68c2c 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJavaArrayIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJavaArrayIterator.java @@ -55,4 +55,4 @@ final class ReverseJavaArrayIterator extends JavaArrayIterator { protected long bumpIndex() { return index--; } -} \ No newline at end of file +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java index 45451a8bad7..f9491dec2e9 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java @@ -140,7 +140,7 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { @SuppressWarnings("unused") private static Object get(final Object jsobj, final Object key) { if (key instanceof Integer) { - return ((JSObject)jsobj).getSlot((int)(Integer)key); + return ((JSObject)jsobj).getSlot((Integer)key); } else if (key instanceof Number) { final int index = getIndex((Number)key); if (index > -1) { @@ -155,7 +155,7 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { @SuppressWarnings("unused") private static void put(final Object jsobj, final Object key, final Object value) { if (key instanceof Integer) { - ((JSObject)jsobj).setSlot((int)(Integer)key, value); + ((JSObject)jsobj).setSlot((Integer)key, value); } else if (key instanceof Number) { ((JSObject)jsobj).setSlot(getIndex((Number)key), value); } else if (key instanceof String) { diff --git a/nashorn/test/script/basic/JDK-8026137.js b/nashorn/test/script/basic/JDK-8026137.js new file mode 100644 index 00000000000..4a19643f327 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026137.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026137: Binary evaluation order in JavaScript is load load + * convert convert, not load convert load convert. + * + * @test + * @run + */ + +try { + (function f() { Object.defineProperty({},"x",{get: function(){return {valueOf:function(){throw 0}}}}).x - Object.defineProperty({},"x",{get: function(){throw 1}}).x })() +} +catch (e) { + print(e); +} + +try { + ({valueOf: function(){throw 0}}) - ({valueOf: function(){throw 1}} - 1) +} catch (e) { + print(e); +} + diff --git a/nashorn/test/script/basic/JDK-8026137.js.EXPECTED b/nashorn/test/script/basic/JDK-8026137.js.EXPECTED new file mode 100644 index 00000000000..6ed281c757a --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026137.js.EXPECTED @@ -0,0 +1,2 @@ +1 +1 From b90addac580311f018776cf05f23b2e12e249339 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Wed, 9 Oct 2013 11:05:17 -0700 Subject: [PATCH 035/152] 8020750: Node::get_int: guarantee(t != NULL) failed: must be con Reviewed-by: kvn, roland --- hotspot/src/share/vm/opto/ifnode.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 7400e939b98..ee54c4fc40d 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -689,6 +689,7 @@ Node* IfNode::fold_compares(PhaseGVN* phase) { ctrl->in(0)->in(1)->is_Bool() && ctrl->in(0)->in(1)->in(1)->Opcode() == Op_CmpI && ctrl->in(0)->in(1)->in(1)->in(2)->is_Con() && + ctrl->in(0)->in(1)->in(1)->in(2) != phase->C->top() && ctrl->in(0)->in(1)->in(1)->in(1) == n) { IfNode* dom_iff = ctrl->in(0)->as_If(); Node* otherproj = dom_iff->proj_out(!ctrl->as_Proj()->_con); From 62fc4be9cbfd58dd153f914af51f7579cd33841a Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 9 Oct 2013 21:45:28 -0400 Subject: [PATCH 036/152] 8025185: MethodHandleInError and MethodTypeInError not handled in ConstantPool::compare_entry_to and copy_entry_to Add missing cases. Reviewed-by: sspitsyn, dcubed --- hotspot/src/share/vm/oops/constantPool.cpp | 53 ++++++++++++---------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 27f1d84020e..fa13d05d598 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -864,6 +864,19 @@ void ConstantPool::unreference_symbols() { } +jbyte normalize_error_tag(jbyte tag) { + switch (tag) { + case JVM_CONSTANT_UnresolvedClassInError: + return JVM_CONSTANT_UnresolvedClass; + case JVM_CONSTANT_MethodHandleInError: + return JVM_CONSTANT_MethodHandle; + case JVM_CONSTANT_MethodTypeInError: + return JVM_CONSTANT_MethodType; + default: + return tag; + } +} + // Compare this constant pool's entry at index1 to the constant pool // cp2's entry at index2. bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2, @@ -873,14 +886,10 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2, jbyte t2 = cp2->tag_at(index2).value(); - // JVM_CONSTANT_UnresolvedClassInError is equal to JVM_CONSTANT_UnresolvedClass - // when comparing - if (t1 == JVM_CONSTANT_UnresolvedClassInError) { - t1 = JVM_CONSTANT_UnresolvedClass; - } - if (t2 == JVM_CONSTANT_UnresolvedClassInError) { - t2 = JVM_CONSTANT_UnresolvedClass; - } + // JVM_CONSTANT_UnresolvedClassInError tag is equal to JVM_CONSTANT_UnresolvedClass + // when comparing (and the other error tags) + t1 = normalize_error_tag(t1); + t2 = normalize_error_tag(t2); if (t1 != t2) { // Not the same entry type so there is nothing else to check. Note @@ -1001,8 +1010,8 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2, case JVM_CONSTANT_MethodType: { - int k1 = method_type_index_at(index1); - int k2 = cp2->method_type_index_at(index2); + int k1 = method_type_index_at_error_ok(index1); + int k2 = cp2->method_type_index_at_error_ok(index2); bool match = compare_entry_to(k1, cp2, k2, CHECK_false); if (match) { return true; @@ -1011,11 +1020,11 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2, case JVM_CONSTANT_MethodHandle: { - int k1 = method_handle_ref_kind_at(index1); - int k2 = cp2->method_handle_ref_kind_at(index2); + int k1 = method_handle_ref_kind_at_error_ok(index1); + int k2 = cp2->method_handle_ref_kind_at_error_ok(index2); if (k1 == k2) { - int i1 = method_handle_index_at(index1); - int i2 = cp2->method_handle_index_at(index2); + int i1 = method_handle_index_at_error_ok(index1); + int i2 = cp2->method_handle_index_at_error_ok(index2); bool match = compare_entry_to(i1, cp2, i2, CHECK_false); if (match) { return true; @@ -1329,14 +1338,6 @@ void ConstantPool::copy_entry_to(constantPoolHandle from_cp, int from_i, } } break; - case JVM_CONSTANT_UnresolvedClassInError: - { - Symbol* k = from_cp->unresolved_klass_at(from_i); - to_cp->unresolved_klass_at_put(to_i, k); - to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError); - } break; - - case JVM_CONSTANT_String: { Symbol* s = from_cp->unresolved_string_at(from_i); @@ -1352,15 +1353,17 @@ void ConstantPool::copy_entry_to(constantPoolHandle from_cp, int from_i, } break; case JVM_CONSTANT_MethodType: + case JVM_CONSTANT_MethodTypeInError: { - jint k = from_cp->method_type_index_at(from_i); + jint k = from_cp->method_type_index_at_error_ok(from_i); to_cp->method_type_index_at_put(to_i, k); } break; case JVM_CONSTANT_MethodHandle: + case JVM_CONSTANT_MethodHandleInError: { - int k1 = from_cp->method_handle_ref_kind_at(from_i); - int k2 = from_cp->method_handle_index_at(from_i); + int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i); + int k2 = from_cp->method_handle_index_at_error_ok(from_i); to_cp->method_handle_index_at_put(to_i, k1, k2); } break; From 3e4c0741c4f7e52976f5744207f0c7fec2922aad Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Thu, 10 Oct 2013 08:51:55 +0200 Subject: [PATCH 037/152] 8021237: clean up JavacAnnotatedConstruct Refactored the static helper methods in JavacAnnoConstructs into ordinary methods and put them in a common superclass (AnnoConstruct) of Symbol and Type. Reviewed-by: jjg, vromero, jfranck --- .../sun/tools/javac/code/AnnoConstruct.java | 238 ++++++++++ .../com/sun/tools/javac/code/Symbol.java | 89 +++- .../com/sun/tools/javac/code/Type.java | 18 +- .../javac/model/JavacAnnoConstructs.java | 445 ------------------ 4 files changed, 310 insertions(+), 480 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java delete mode 100644 langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java b/langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java new file mode 100644 index 00000000000..052336bbf2b --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.javac.code; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import javax.lang.model.AnnotatedConstruct; + +import com.sun.tools.javac.model.AnnotationProxyMaker; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.ListBuffer; + +/** + * Common super type for annotated constructs such as Types and Symbols. + * + * This class should *not* contain any fields since it would have a significant + * impact on the javac memory footprint. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

    + */ +public abstract class AnnoConstruct implements AnnotatedConstruct { + + + // Override to enforce a narrower return type. + @Override + public abstract List getAnnotationMirrors(); + + + // This method is part of the javax.lang.model API, do not use this in javac code. + protected Attribute.Compound getAttribute(Class annoType) { + String name = annoType.getName(); + + for (Attribute.Compound anno : getAnnotationMirrors()) { + if (name.equals(anno.type.tsym.flatName().toString())) + return anno; + } + + return null; + } + + + @SuppressWarnings("unchecked") + protected A[] getInheritedAnnotations(Class annoType) { + return (A[]) java.lang.reflect.Array.newInstance(annoType, 0); // annoType is the Class for A + } + + + // This method is part of the javax.lang.model API, do not use this in javac code. + public A[] getAnnotationsByType(Class annoType) { + + if (!annoType.isAnnotation()) + throw new IllegalArgumentException("Not an annotation type: " + + annoType); + // If annoType does not declare a container this is equivalent to wrapping + // getAnnotation(...) in an array. + Class containerType = getContainer(annoType); + if (containerType == null) { + A res = getAnnotation(annoType); + int size = res == null ? 0 : 1; + + @SuppressWarnings("unchecked") // annoType is the Class for A + A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); + if (res != null) + arr[0] = res; + return arr; + } + + // So we have a containing type + String annoTypeName = annoType.getName(); + String containerTypeName = containerType.getName(); + int directIndex = -1, containerIndex = -1; + Attribute.Compound direct = null, container = null; + // Find directly (explicit or implicit) present annotations + int index = -1; + for (Attribute.Compound attribute : getAnnotationMirrors()) { + index++; + if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) { + directIndex = index; + direct = attribute; + } else if(containerTypeName != null && + attribute.type.tsym.flatName().contentEquals(containerTypeName)) { + containerIndex = index; + container = attribute; + } + } + + // Deal with inherited annotations + if (direct == null && container == null) + return getInheritedAnnotations(annoType); + + // Pack them in an array + Attribute[] contained0 = null; + if (container != null) + contained0 = unpackAttributes(container); + ListBuffer compounds = new ListBuffer<>(); + if (contained0 != null) { + for (Attribute a : contained0) + if (a instanceof Attribute.Compound) + compounds = compounds.append((Attribute.Compound)a); + } + Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]); + + int size = (direct == null ? 0 : 1) + contained.length; + @SuppressWarnings("unchecked") // annoType is the Class for A + A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); + + // if direct && container, which is first? + int insert = -1; + int length = arr.length; + if (directIndex >= 0 && containerIndex >= 0) { + if (directIndex < containerIndex) { + arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); + insert = 1; + } else { + arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType); + insert = 0; + length--; + } + } else if (directIndex >= 0) { + arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); + return arr; + } else { + // Only container + insert = 0; + } + + for (int i = 0; i + insert < length; i++) + arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType); + + return arr; + } + + + // This method is part of the javax.lang.model API, do not use this in javac code. + public A getAnnotation(Class annoType) { + + if (!annoType.isAnnotation()) + throw new IllegalArgumentException("Not an annotation type: " + annoType); + + Attribute.Compound c = getAttribute(annoType); + return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); + } + + // Needed to unpack the runtime view of containing annotations + private static final Class REPEATABLE_CLASS = initRepeatable(); + private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); + + private static Class initRepeatable() { + try { + // Repeatable will not be available when bootstrapping on + // JDK 7 so use a reflective lookup instead of a class + // literal for Repeatable.class. + return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class); + } catch (ClassNotFoundException | SecurityException e) { + return null; + } + } + + private static Method initValueElementMethod() { + if (REPEATABLE_CLASS == null) + return null; + + Method m = null; + try { + m = REPEATABLE_CLASS.getMethod("value"); + if (m != null) + m.setAccessible(true); + return m; + } catch (NoSuchMethodException e) { + return null; + } + } + + + // Helper to getAnnotationsByType + private static Class getContainer(Class annoType) { + // Since we can not refer to java.lang.annotation.Repeatable until we are + // bootstrapping with java 8 we need to get the Repeatable annotation using + // reflective invocations instead of just using its type and element method. + if (REPEATABLE_CLASS != null && + VALUE_ELEMENT_METHOD != null) { + // Get the Repeatable instance on the annotations declaration + Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS); + if (repeatable != null) { + try { + // Get the value element, it should be a class + // indicating the containing annotation type + @SuppressWarnings("unchecked") + Class containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable); + if (containerType == null) + return null; + + return containerType; + } catch (ClassCastException | IllegalAccessException | InvocationTargetException e) { + return null; + } + } + } + return null; + } + + + // Helper to getAnnotationsByType + private static Attribute[] unpackAttributes(Attribute.Compound container) { + // We now have an instance of the container, + // unpack it returning an instance of the + // contained type or null + return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values; + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 6d9eea79046..5efd2b66b7c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -25,6 +25,8 @@ package com.sun.tools.javac.code; +import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; import java.util.Set; import java.util.concurrent.Callable; @@ -37,8 +39,6 @@ import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.jvm.*; -import com.sun.tools.javac.model.*; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.Name; import static com.sun.tools.javac.code.Flags.*; @@ -58,8 +58,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; * This code and its internal interfaces are subject to change or * deletion without notice. */ -public abstract class Symbol implements Element { - // public Throwable debug = new Throwable(); +public abstract class Symbol extends AnnoConstruct implements Element { /** The kind of this symbol. * @see Kinds @@ -103,6 +102,7 @@ public abstract class Symbol implements Element { */ protected SymbolMetadata annotations; + /** An accessor method for the attributes of this symbol. * Attributes of class symbols should be accessed through the accessor * method to make sure that the class symbol is loaded. @@ -596,18 +596,6 @@ public abstract class Symbol implements Element { return getRawAttributes(); } - /** - * @deprecated this method should never be used by javac internally. - */ - @Deprecated - public A getAnnotation(Class annoType) { - return JavacAnnoConstructs.getAnnotation(this, annoType); - } - - // This method is part of the javax.lang.model API, do not use this in javac code. - public A[] getAnnotationsByType(Class annoType) { - return JavacAnnoConstructs.getAnnotationsByType(this, annoType); - } // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList public java.util.List getEnclosedElements() { @@ -793,6 +781,28 @@ public abstract class Symbol implements Element { return res = res.reverse(); } + + + // Helper to getAnnotation[s] + @Override + public Attribute.Compound getAttribute(Class annoType) { + + String name = annoType.getName(); + + // Declaration annotations on type variables are stored in type attributes + // on the owner of the TypeVariableSymbol + List candidates = owner.getRawTypeAttributes(); + for (Attribute.TypeCompound anno : candidates) + if (anno.position.type == TargetType.CLASS_TYPE_PARAMETER || + anno.position.type == TargetType.METHOD_TYPE_PARAMETER) + if (name.contentEquals(anno.type.tsym.flatName())) + return anno; + + return null; + } + + + @Override public R accept(ElementVisitor v, P p) { return v.visitTypeParameter(this, p); @@ -1049,6 +1059,31 @@ public abstract class Symbol implements Element { } } + /** + * Returns the next class to search for inherited annotations or {@code null} + * if the next class can't be found. + */ + private ClassSymbol getSuperClassToSearchForAnnotations() { + + Type sup = getSuperclass(); + + if (!sup.hasTag(CLASS) || sup.isErroneous()) + return null; + + return (ClassSymbol) sup.tsym; + } + + + @Override + protected A[] getInheritedAnnotations(Class annoType) { + + ClassSymbol sup = getSuperClassToSearchForAnnotations(); + + return sup == null ? super.getInheritedAnnotations(annoType) + : sup.getAnnotationsByType(annoType); + } + + public ElementKind getKind() { long flags = flags(); if ((flags & ANNOTATION) != 0) @@ -1079,15 +1114,25 @@ public abstract class Symbol implements Element { return NestingKind.MEMBER; } - /** - * Since this method works in terms of the runtime representation - * of annotations, it should never be used by javac internally. - */ + @Override - public A getAnnotation(Class annoType) { - return JavacAnnoConstructs.getAnnotation(this, annoType); + protected Attribute.Compound getAttribute(final Class annoType) { + + Attribute.Compound attrib = super.getAttribute(annoType); + + boolean inherited = annoType.isAnnotationPresent(Inherited.class); + if (attrib != null || !inherited) + return attrib; + + // Search supertypes + ClassSymbol superType = getSuperClassToSearchForAnnotations(); + return superType == null ? null + : superType.getAttribute(annoType); } + + + public R accept(ElementVisitor v, P p) { return v.visitType(this, p); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index 56e4d411ac8..269fed3d846 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -35,7 +35,6 @@ import java.util.Set; import javax.lang.model.type.*; import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.model.JavacAnnoConstructs; import com.sun.tools.javac.util.*; import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; @@ -70,7 +69,7 @@ import static com.sun.tools.javac.code.TypeTag.*; * * @see TypeTag */ -public abstract class Type implements TypeMirror { +public abstract class Type extends AnnoConstruct implements TypeMirror { /** Constant type: no type at all. */ public static final JCNoType noType = new JCNoType(); @@ -233,15 +232,17 @@ public abstract class Type implements TypeMirror { } @Override - public List getAnnotationMirrors() { + public List getAnnotationMirrors() { return List.nil(); } + @Override public A getAnnotation(Class annotationType) { return null; } + @Override public A[] getAnnotationsByType(Class annotationType) { @SuppressWarnings("unchecked") @@ -1846,19 +1847,10 @@ public abstract class Type implements TypeMirror { } @Override - public List getAnnotationMirrors() { + public List getAnnotationMirrors() { return typeAnnotations; } - @Override - public A getAnnotation(Class annotationType) { - return JavacAnnoConstructs.getAnnotation(this, annotationType); - } - - @Override - public A[] getAnnotationsByType(Class annotationType) { - return JavacAnnoConstructs.getAnnotationsByType(this, annotationType); - } @Override public TypeKind getKind() { diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java deleted file mode 100644 index c05662cbcbb..00000000000 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.sun.tools.javac.model; - -import java.lang.annotation.Annotation; -import java.lang.annotation.Inherited; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.sun.tools.javac.code.Attribute; -import com.sun.tools.javac.code.Kinds; -import com.sun.tools.javac.code.Symbol; -import com.sun.tools.javac.code.Symbol.ClassSymbol; -import com.sun.tools.javac.code.Symbol.TypeVariableSymbol; -import com.sun.tools.javac.code.TargetType; -import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.Type.AnnotatedType; -import com.sun.tools.javac.util.ListBuffer; -import static com.sun.tools.javac.code.TypeTag.CLASS; -import com.sun.tools.javac.util.List; - -/** - * Utility methods for operating on annotated constructs. - * - *

    This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own - * risk. This code and its internal interfaces are subject to change - * or deletion without notice.

    - */ -public class JavacAnnoConstructs { - - // - - /** - * An internal-use utility that creates a runtime view of an - * annotation. This is the implementation of - * Element.getAnnotation(Class). - */ - public static
    A getAnnotation(Symbol annotated, - Class annoType) { - if (!annoType.isAnnotation()) - throw new IllegalArgumentException("Not an annotation type: " - + annoType); - Attribute.Compound c; - if (annotated.kind == Kinds.TYP && - annotated instanceof ClassSymbol) { - c = getAttributeOnClass((ClassSymbol)annotated, annoType); - } else if (annotated.kind == Kinds.TYP && - annotated instanceof TypeVariableSymbol) { - c = getAttributeOnTypeVariable((TypeVariableSymbol)annotated, annoType); - } else { - c = getAttribute(annotated, annoType); - } - return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); - } - - // Helper to getAnnotation[s] - private static Attribute.Compound getAttribute(Symbol annotated, - Class annoType) { - String name = annoType.getName(); - - for (Attribute.Compound anno : annotated.getRawAttributes()) { - if (name.equals(anno.type.tsym.flatName().toString())) - return anno; - } - - return null; - } - - // Helper to getAnnotation[s] - private static Attribute.Compound - getAttributeOnTypeVariable(TypeVariableSymbol annotated, Class annoType) { - String name = annoType.getName(); - - // Declaration annotations on type variables are stored in type attributes - // on the owner of the TypeVariableSymbol - List res = List.nil(); - List candidates = annotated.owner.getRawTypeAttributes(); - for (Attribute.TypeCompound anno : candidates) - if (anno.position.type == TargetType.CLASS_TYPE_PARAMETER || - anno.position.type == TargetType.METHOD_TYPE_PARAMETER) - if (name.equals(anno.type.tsym.flatName().toString())) - return anno; - - return null; - } - - // Helper to getAnnotation[s] - private static Attribute.Compound getAttributeOnClass( - ClassSymbol annotated, - final Class annoType) - { - boolean inherited = annoType.isAnnotationPresent(Inherited.class); - Attribute.Compound result = null; - - result = getAttribute(annotated, annoType); - if (result != null || !inherited) - return result; - - while ((annotated = nextSupertypeToSearch(annotated)) != null) { - result = getAttribute(annotated, annoType); - if (result != null) - return result; - } - return null; // no more supertypes to search - } - - /** - * Returns the next type to search for inherited annotations or {@code null} - * if the next type can't be found. - */ - private static ClassSymbol nextSupertypeToSearch(ClassSymbol annotated) { - if (annotated.name == annotated.name.table.names.java_lang_Object) - return null; - - Type sup = annotated.getSuperclass(); - if (!sup.hasTag(CLASS) || sup.isErroneous()) - return null; - - return (ClassSymbol) sup.tsym; - } - - /** - * An internal-use utility that creates a runtime view of - * annotations. This is the implementation of - * Element.getAnnotations(Class). - */ - public static A[] getAnnotationsByType(Symbol annotated, - Class annoType) - { - if (!annoType.isAnnotation()) - throw new IllegalArgumentException("Not an annotation type: " - + annoType); - // If annoType does not declare a container this is equivalent to wrapping - // getAnnotation(...) in an array. - Class containerType = getContainer(annoType); - if (containerType == null) { - A res = getAnnotation(annotated, annoType); - int size; - if (res == null) { - size = 0; - } else { - size = 1; - } - @SuppressWarnings("unchecked") // annoType is the Class for A - A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); - if (res != null) - arr[0] = res; - return arr; - } - - // So we have a containing type - String annoTypeName = annoType.getName(); - String containerTypeName = containerType.getName(); - int directIndex = -1, containerIndex = -1; - Attribute.Compound direct = null, container = null; - // Find directly (explicit or implicit) present annotations - int index = -1; - for (List list = annotated.getAnnotationMirrors(); - !list.isEmpty(); - list = list.tail) { - Attribute.Compound attribute = list.head; - index++; - if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) { - directIndex = index; - direct = attribute; - } else if(containerTypeName != null && - attribute.type.tsym.flatName().contentEquals(containerTypeName)) { - containerIndex = index; - container = attribute; - } - } - - // Deal with inherited annotations - if (direct == null && container == null) { - if (annotated.kind == Kinds.TYP && - (annotated instanceof ClassSymbol)) { - ClassSymbol s = nextSupertypeToSearch((ClassSymbol)annotated); - if (s != null) - return getAnnotationsByType(s, annoType); - } - } - - // Pack them in an array - Attribute[] contained0 = null; - if (container != null) - contained0 = unpackAttributes(container); - ListBuffer compounds = new ListBuffer<>(); - if (contained0 != null) { - for (Attribute a : contained0) - if (a instanceof Attribute.Compound) - compounds = compounds.append((Attribute.Compound)a); - } - Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]); - - int size = (direct == null ? 0 : 1) + contained.length; - @SuppressWarnings("unchecked") // annoType is the Class for A - A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); - - // if direct && container, which is first? - int insert = -1; - int length = arr.length; - if (directIndex >= 0 && containerIndex >= 0) { - if (directIndex < containerIndex) { - arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); - insert = 1; - } else { - arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType); - insert = 0; - length--; - } - } else if (directIndex >= 0) { - arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); - return arr; - } else { - // Only container - insert = 0; - } - - for (int i = 0; i + insert < length; i++) - arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType); - - return arr; - } - - // - - // - - /** - * An internal-use utility that creates a runtime view of an - * annotation. This is the implementation of - * TypeMirror.getAnnotation(Class). - */ - public static A getAnnotation(AnnotatedType annotated, Class annoType) { - if (!annoType.isAnnotation()) - throw new IllegalArgumentException("Not an annotation type: " - + annoType); - Attribute.Compound c = getAttribute(annotated, annoType); - return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); - } - - // Helper to getAnnotation[s] - private static Attribute.Compound getAttribute(Type annotated, - Class annoType) { - String name = annoType.getName(); - - for (Attribute.Compound anno : annotated.getAnnotationMirrors()) { - if (name.equals(anno.type.tsym.flatName().toString())) - return anno; - } - - return null; - } - - /** - * An internal-use utility that creates a runtime view of - * annotations. This is the implementation of - * TypeMirror.getAnnotationsByType(Class). - */ - public static A[] getAnnotationsByType(AnnotatedType annotated, Class annoType) { - if (!annoType.isAnnotation()) - throw new IllegalArgumentException("Not an annotation type: " - + annoType); - // If annoType does not declare a container this is equivalent to wrapping - // getAnnotation(...) in an array. - Class containerType = getContainer(annoType); - if (containerType == null) { - A res = getAnnotation(annotated, annoType); - int size; - if (res == null) { - size = 0; - } else { - size = 1; - } - @SuppressWarnings("unchecked") // annoType is the Class for A - A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); - if (res != null) - arr[0] = res; - return arr; - } - - // So we have a containing type - String annoTypeName = annoType.getName(); - String containerTypeName = containerType.getName(); - int directIndex = -1, containerIndex = -1; - Attribute.Compound direct = null, container = null; - // Find directly (explicit or implicit) present annotations - int index = -1; - for (List list = annotated.getAnnotationMirrors(); - !list.isEmpty(); - list = list.tail) { - Attribute.Compound attribute = list.head; - index++; - if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) { - directIndex = index; - direct = attribute; - } else if(containerTypeName != null && - attribute.type.tsym.flatName().contentEquals(containerTypeName)) { - containerIndex = index; - container = attribute; - } - } - - // Pack them in an array - Attribute[] contained0 = null; - if (container != null) - contained0 = unpackAttributes(container); - ListBuffer compounds = new ListBuffer<>(); - if (contained0 != null) { - for (Attribute a : contained0) - if (a instanceof Attribute.Compound) - compounds = compounds.append((Attribute.Compound)a); - } - Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]); - - int size = (direct == null ? 0 : 1) + contained.length; - @SuppressWarnings("unchecked") // annoType is the Class for A - A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); - - // if direct && container, which is first? - int insert = -1; - int length = arr.length; - if (directIndex >= 0 && containerIndex >= 0) { - if (directIndex < containerIndex) { - arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); - insert = 1; - } else { - arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType); - insert = 0; - length--; - } - } else if (directIndex >= 0) { - arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); - return arr; - } else { - // Only container - insert = 0; - } - - for (int i = 0; i + insert < length; i++) - arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType); - - return arr; - } - - // - - // - - // Needed to unpack the runtime view of containing annotations - private static final Class REPEATABLE_CLASS = initRepeatable(); - private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); - - private static Class initRepeatable() { - try { - // Repeatable will not be available when bootstrapping on - // JDK 7 so use a reflective lookup instead of a class - // literal for Repeatable.class. - return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class); - } catch (ClassNotFoundException e) { - return null; - } catch (SecurityException e) { - return null; - } - } - - private static Method initValueElementMethod() { - if (REPEATABLE_CLASS == null) - return null; - - Method m = null; - try { - m = REPEATABLE_CLASS.getMethod("value"); - if (m != null) - m.setAccessible(true); - return m; - } catch (NoSuchMethodException e) { - return null; - } - } - - // Helper to getAnnotations - private static Class getContainer(Class annoType) { - // Since we can not refer to java.lang.annotation.Repeatable until we are - // bootstrapping with java 8 we need to get the Repeatable annotation using - // reflective invocations instead of just using its type and element method. - if (REPEATABLE_CLASS != null && - VALUE_ELEMENT_METHOD != null) { - // Get the Repeatable instance on the annotations declaration - Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS); - if (repeatable != null) { - try { - // Get the value element, it should be a class - // indicating the containing annotation type - @SuppressWarnings("unchecked") - Class containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable); - if (containerType == null) - return null; - - return containerType; - } catch (ClassCastException e) { - return null; - } catch (IllegalAccessException e) { - return null; - } catch (InvocationTargetException e ) { - return null; - } - } - } - return null; - } - - // Helper to getAnnotations - private static Attribute[] unpackAttributes(Attribute.Compound container) { - // We now have an instance of the container, - // unpack it returning an instance of the - // contained type or null - return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values; - } - - // -} From d5dda0a437f404f096bbf2c6ea4839142c60fe56 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 10 Oct 2013 11:48:56 +0200 Subject: [PATCH 038/152] 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases Reviewed-by: lagergren, jlaskey --- .../internal/codegen/CompilationPhase.java | 2 +- .../jdk/nashorn/internal/codegen/Lower.java | 14 ++++-- .../internal/runtime/CodeInstaller.java | 6 +++ .../jdk/nashorn/internal/runtime/Context.java | 13 +++++ nashorn/test/script/assert.js | 19 +++++++ nashorn/test/script/basic/JDK-8019508.js | 2 +- .../test/script/basic/JDK-8019508.js.EXPECTED | 8 +-- nashorn/test/script/basic/JDK-8019553.js | 2 +- .../test/script/basic/JDK-8019553.js.EXPECTED | 8 +-- nashorn/test/script/basic/JDK-8019791.js | 4 +- .../test/script/basic/JDK-8019791.js.EXPECTED | 4 +- nashorn/test/script/basic/JDK-8019805.js | 2 +- .../test/script/basic/JDK-8019805.js.EXPECTED | 2 +- nashorn/test/script/basic/JDK-8026167.js | 50 +++++++++++++++++++ nashorn/test/script/basic/NASHORN-100.js | 2 +- .../test/script/basic/NASHORN-100.js.EXPECTED | 2 +- nashorn/test/script/basic/NASHORN-293.js | 6 +-- .../test/script/basic/NASHORN-293.js.EXPECTED | 12 ++--- nashorn/test/script/basic/NASHORN-40.js | 4 +- .../test/script/basic/NASHORN-40.js.EXPECTED | 4 +- nashorn/test/script/basic/NASHORN-51.js | 8 +-- .../test/script/basic/NASHORN-51.js.EXPECTED | 48 +++++++++--------- nashorn/test/script/basic/NASHORN-98.js | 4 +- .../test/script/basic/NASHORN-98.js.EXPECTED | 4 +- nashorn/test/script/basic/eval.js | 2 +- nashorn/test/script/basic/eval.js.EXPECTED | 2 +- 26 files changed, 164 insertions(+), 70 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026167.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java index be8faab93d0..7a9054f6462 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java @@ -162,7 +162,7 @@ enum CompilationPhase { LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { - return (FunctionNode)fn.accept(new Lower()); + return (FunctionNode)fn.accept(new Lower(compiler)); } @Override diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java index 032d27bc5bb..d60fe0fcee1 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java @@ -86,10 +86,13 @@ final class Lower extends NodeOperatorVisitor { private static final DebugLogger LOG = new DebugLogger("lower"); + // needed only to get unique eval id from code installer + private final Compiler compiler; + /** * Constructor. */ - Lower() { + Lower(final Compiler compiler) { super(new BlockLexicalContext() { @Override @@ -132,6 +135,7 @@ final class Lower extends NodeOperatorVisitor { return block.setIsTerminal(this, false); } }); + this.compiler = compiler; } @Override @@ -529,11 +533,15 @@ final class Lower extends NodeOperatorVisitor { */ private String evalLocation(final IdentNode node) { final Source source = lc.getCurrentFunction().getSource(); + final int pos = node.position(); return new StringBuilder(). append(source.getName()). append('#'). - append(source.getLine(node.position())). - append(""). + append(source.getLine(pos)). + append(':'). + append(source.getColumn(pos)). + append("@"). + append(compiler.getCodeInstaller().getUniqueEvalId()). toString(); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java index be9976e7d84..28c9630ea54 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java @@ -68,4 +68,10 @@ public interface CodeInstaller { * @return unique script id */ public long getUniqueScriptId(); + + /** + * Get next unique eval id + * @return unique eval id + */ + public long getUniqueEvalId(); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index d31a8ab369f..056d6d51437 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -139,6 +139,11 @@ public final class Context { public long getUniqueScriptId() { return context.getUniqueScriptId(); } + + @Override + public long getUniqueEvalId() { + return context.getUniqueEvalId(); + } } /** Is Context global debug mode enabled ? */ @@ -238,6 +243,9 @@ public final class Context { /** Unique id for script. Used only when --loader-per-compile=false */ private final AtomicLong uniqueScriptId; + /** Unique id for 'eval' */ + private final AtomicLong uniqueEvalId; + private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; @@ -320,6 +328,7 @@ public final class Context { this.uniqueScriptId = new AtomicLong(); } this.errors = errors; + this.uniqueEvalId = new AtomicLong(); // if user passed -classpath option, make a class loader with that and set it as // thread context class loader so that script can access classes from that path. @@ -954,6 +963,10 @@ public final class Context { }, CREATE_LOADER_ACC_CTXT); } + private long getUniqueEvalId() { + return uniqueEvalId.getAndIncrement(); + } + private long getUniqueScriptId() { return uniqueScriptId.getAndIncrement(); } diff --git a/nashorn/test/script/assert.js b/nashorn/test/script/assert.js index 25bc2599042..3656f86c373 100644 --- a/nashorn/test/script/assert.js +++ b/nashorn/test/script/assert.js @@ -61,3 +61,22 @@ Object.defineProperty(this, "fail", { } } }); + +Object.defineProperty(this, "printError", { + configuable: true, + enumerable: false, + writable: true, + value: function (e) { + var msg = e.message; + var str = e.name + ':'; + if (e.lineNumber > 0) { + str += e.lineNumber + ':'; + } + if (e.columnNumber > 0) { + str += e.columnNumber + ':'; + } + str += msg.substring(msg.indexOf(' ') + 1); + print(str); + } +}); + diff --git a/nashorn/test/script/basic/JDK-8019508.js b/nashorn/test/script/basic/JDK-8019508.js index d23035c638a..88ecbec386e 100644 --- a/nashorn/test/script/basic/JDK-8019508.js +++ b/nashorn/test/script/basic/JDK-8019508.js @@ -36,7 +36,7 @@ function checkObjLiteral(str) { if (! (e instanceof SyntaxError)) { fail("expected SyntaxError, got " + e); } - print(e.message.replace(/\\/g, '/')); + printError(e); } } diff --git a/nashorn/test/script/basic/JDK-8019508.js.EXPECTED b/nashorn/test/script/basic/JDK-8019508.js.EXPECTED index d5f81409803..a3d883f0cfe 100644 --- a/nashorn/test/script/basic/JDK-8019508.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8019508.js.EXPECTED @@ -1,12 +1,12 @@ -test/script/basic/JDK-8019508.js#33:1:2 Expected property id but found , +SyntaxError:33:Expected property id but found , ({,}) ^ -test/script/basic/JDK-8019508.js#33:1:2 Expected property id but found , +SyntaxError:33:Expected property id but found , ({, a:2 }) ^ -test/script/basic/JDK-8019508.js#33:1:6 Expected property id but found , +SyntaxError:33:Expected property id but found , ({a:3,,}) ^ -test/script/basic/JDK-8019508.js#33:1:6 Expected comma but found ident +SyntaxError:33:Expected comma but found ident ({a:3 b:2} ^ diff --git a/nashorn/test/script/basic/JDK-8019553.js b/nashorn/test/script/basic/JDK-8019553.js index d754618718a..bec3a52802e 100644 --- a/nashorn/test/script/basic/JDK-8019553.js +++ b/nashorn/test/script/basic/JDK-8019553.js @@ -33,7 +33,7 @@ function check(str) { eval(str); fail("SyntaxError expected for: " + str); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } } diff --git a/nashorn/test/script/basic/JDK-8019553.js.EXPECTED b/nashorn/test/script/basic/JDK-8019553.js.EXPECTED index 78d22beac0f..38e52866b72 100644 --- a/nashorn/test/script/basic/JDK-8019553.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8019553.js.EXPECTED @@ -1,12 +1,12 @@ -SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found + +SyntaxError:33:Expected l-value but found + ++ +3 ^ -SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found - +SyntaxError:33:Expected l-value but found - ++ -7 ^ -SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found + +SyntaxError:33:Expected l-value but found + -- +2 ^ -SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found - +SyntaxError:33:Expected l-value but found - -- -8 ^ diff --git a/nashorn/test/script/basic/JDK-8019791.js b/nashorn/test/script/basic/JDK-8019791.js index 75e92819d89..ad32ce3c068 100644 --- a/nashorn/test/script/basic/JDK-8019791.js +++ b/nashorn/test/script/basic/JDK-8019791.js @@ -33,7 +33,7 @@ try { eval('"" ~ ""'); print("FAILED: SyntaxError expected for: \"\" ~ \"\""); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } // Used to crash instead of SyntaxError @@ -41,7 +41,7 @@ try { eval("function() { if (1~0) return 0; return 1 }"); print("FAILED: SyntaxError expected for: if (1~0) "); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } // The following are valid, but used to crash diff --git a/nashorn/test/script/basic/JDK-8019791.js.EXPECTED b/nashorn/test/script/basic/JDK-8019791.js.EXPECTED index 5aec5909ada..b214b2c6504 100644 --- a/nashorn/test/script/basic/JDK-8019791.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8019791.js.EXPECTED @@ -1,6 +1,6 @@ -SyntaxError: test/script/basic/JDK-8019791.js#33:1:3 Expected ; but found ~ +SyntaxError:33:Expected ; but found ~ "" ~ "" ^ -SyntaxError: test/script/basic/JDK-8019791.js#41:1:18 Expected ) but found ~ +SyntaxError:41:Expected ) but found ~ function() { if (1~0) return 0; return 1 } ^ diff --git a/nashorn/test/script/basic/JDK-8019805.js b/nashorn/test/script/basic/JDK-8019805.js index 70371fb85e0..7e3e25b5dbc 100644 --- a/nashorn/test/script/basic/JDK-8019805.js +++ b/nashorn/test/script/basic/JDK-8019805.js @@ -32,5 +32,5 @@ try { eval("for each(var v=0;false;);"); print("FAILED: for each(var v=0; false;); should have thrown error"); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } diff --git a/nashorn/test/script/basic/JDK-8019805.js.EXPECTED b/nashorn/test/script/basic/JDK-8019805.js.EXPECTED index 154c3326372..76d335e4583 100644 --- a/nashorn/test/script/basic/JDK-8019805.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8019805.js.EXPECTED @@ -1,3 +1,3 @@ -SyntaxError: test/script/basic/JDK-8019805.js#32:1:16 for each can only be used with for..in +SyntaxError:32:for each can only be used with for..in for each(var v=0;false;); ^ diff --git a/nashorn/test/script/basic/JDK-8026167.js b/nashorn/test/script/basic/JDK-8026167.js new file mode 100644 index 00000000000..4959e62a7a9 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026167.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases. + * + * @test + * @run + */ + +var m = new javax.script.ScriptEngineManager(); +var e = m.getEngineByName('js'); + +// leave the whitespace - need both eval("e") at same column for this test! + +e.eval('function f(e) { eval("e") } f()'); +e.eval('function f() { var e = 33; eval("e") } f()'); + +function f() { + Function.call.call(function x() { eval("x") }); eval("x") +} + +try { + f(); + fail("Should have thrown ReferenceError"); +} catch (e) { + if (! (e instanceof ReferenceError)) { + fail("ReferenceError expected but got " + e); + } +} diff --git a/nashorn/test/script/basic/NASHORN-100.js b/nashorn/test/script/basic/NASHORN-100.js index fdea1cf05be..df81284d020 100644 --- a/nashorn/test/script/basic/NASHORN-100.js +++ b/nashorn/test/script/basic/NASHORN-100.js @@ -35,5 +35,5 @@ try { if (! (e instanceof SyntaxError)) { fail("#2 expected SyntaxError got " + e); } - print(e.toString().replace(/\\/g, '/')); + printError(e); } diff --git a/nashorn/test/script/basic/NASHORN-100.js.EXPECTED b/nashorn/test/script/basic/NASHORN-100.js.EXPECTED index d183bb33cc8..e9c5a253c49 100644 --- a/nashorn/test/script/basic/NASHORN-100.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-100.js.EXPECTED @@ -1,3 +1,3 @@ -SyntaxError: test/script/basic/NASHORN-100.js#32:1:0 Invalid return statement +SyntaxError:32:Invalid return statement return; ^ diff --git a/nashorn/test/script/basic/NASHORN-293.js b/nashorn/test/script/basic/NASHORN-293.js index cd83ec468c9..013714b85da 100644 --- a/nashorn/test/script/basic/NASHORN-293.js +++ b/nashorn/test/script/basic/NASHORN-293.js @@ -40,15 +40,13 @@ for (var i = 0; i < 3; i++) { try { eval(src); } catch (e) { - var location = e.fileName ? e.fileName.slice(-9) : "unknown source"; - print(e.name, "@", location); + printError(e); } } for (var i = 0; i < 3; i++) { try { eval(src); } catch (e) { - var location = e.fileName ? e.fileName.slice(-9) : "unknown source"; - print(e.name, "@", location); + printError(e); } } diff --git a/nashorn/test/script/basic/NASHORN-293.js.EXPECTED b/nashorn/test/script/basic/NASHORN-293.js.EXPECTED index 68278106d32..90fe5f087d7 100644 --- a/nashorn/test/script/basic/NASHORN-293.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-293.js.EXPECTED @@ -1,9 +1,9 @@ hello hello hello -TypeError @ #41 -TypeError @ #41 -TypeError @ #41 -TypeError @ #49 -TypeError @ #49 -TypeError @ #49 +TypeError:1:read property "foo" from undefined +TypeError:1:read property "foo" from undefined +TypeError:1:read property "foo" from undefined +TypeError:1:read property "foo" from undefined +TypeError:1:read property "foo" from undefined +TypeError:1:read property "foo" from undefined diff --git a/nashorn/test/script/basic/NASHORN-40.js b/nashorn/test/script/basic/NASHORN-40.js index f031730bd53..34331ef2dc6 100644 --- a/nashorn/test/script/basic/NASHORN-40.js +++ b/nashorn/test/script/basic/NASHORN-40.js @@ -31,11 +31,11 @@ try { eval("print(.foo)"); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } try { eval(".bar = 3423;"); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } diff --git a/nashorn/test/script/basic/NASHORN-40.js.EXPECTED b/nashorn/test/script/basic/NASHORN-40.js.EXPECTED index 0e03cab3084..94f15980d3c 100644 --- a/nashorn/test/script/basic/NASHORN-40.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-40.js.EXPECTED @@ -1,6 +1,6 @@ -SyntaxError: test/script/basic/NASHORN-40.js#32:1:6 Expected an operand but found . +SyntaxError:32:Expected an operand but found . print(.foo) ^ -SyntaxError: test/script/basic/NASHORN-40.js#38:1:0 Expected an operand but found . +SyntaxError:38:Expected an operand but found . .bar = 3423; ^ diff --git a/nashorn/test/script/basic/NASHORN-51.js b/nashorn/test/script/basic/NASHORN-51.js index bc41d79bebf..45d00e9e610 100644 --- a/nashorn/test/script/basic/NASHORN-51.js +++ b/nashorn/test/script/basic/NASHORN-51.js @@ -35,28 +35,28 @@ for (i in literals) { eval(literals[i] + "++"); print("ERROR!! post increment : " + literals[i]); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } try { eval(literals[i] + "--"); print("ERROR!! post decrement : " + literals[i]); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } try { eval("++" + literals[i]); print("ERROR!! pre increment : " + literals[i]); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } try { eval("--" + literals[i]); print("ERROR!! pre decrement : " + literals[i]); } catch (e) { - print(e.toString().replace(/\\/g, '/')); + printError(e); } } diff --git a/nashorn/test/script/basic/NASHORN-51.js.EXPECTED b/nashorn/test/script/basic/NASHORN-51.js.EXPECTED index 9479f7e1995..5201385604c 100644 --- a/nashorn/test/script/basic/NASHORN-51.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-51.js.EXPECTED @@ -1,72 +1,72 @@ -ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment +ReferenceError:35:Invalid left hand side for assignment 1++ ^ -ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment +ReferenceError:42:Invalid left hand side for assignment 1-- ^ -ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment +ReferenceError:49:Invalid left hand side for assignment ++1 ^ -ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment +ReferenceError:56:Invalid left hand side for assignment --1 ^ -ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment +ReferenceError:35:Invalid left hand side for assignment 0++ ^ -ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment +ReferenceError:42:Invalid left hand side for assignment 0-- ^ -ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment +ReferenceError:49:Invalid left hand side for assignment ++0 ^ -ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment +ReferenceError:56:Invalid left hand side for assignment --0 ^ -ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment +ReferenceError:35:Invalid left hand side for assignment 3.14++ ^ -ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment +ReferenceError:42:Invalid left hand side for assignment 3.14-- ^ -ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment +ReferenceError:49:Invalid left hand side for assignment ++3.14 ^ -ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment +ReferenceError:56:Invalid left hand side for assignment --3.14 ^ -ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment +ReferenceError:35:Invalid left hand side for assignment true++ ^ -ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment +ReferenceError:42:Invalid left hand side for assignment true-- ^ -ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment +ReferenceError:49:Invalid left hand side for assignment ++true ^ -ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment +ReferenceError:56:Invalid left hand side for assignment --true ^ -ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment +ReferenceError:35:Invalid left hand side for assignment false++ ^ -ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment +ReferenceError:42:Invalid left hand side for assignment false-- ^ -ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment +ReferenceError:49:Invalid left hand side for assignment ++false ^ -ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment +ReferenceError:56:Invalid left hand side for assignment --false ^ -ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment +ReferenceError:35:Invalid left hand side for assignment null++ ^ -ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment +ReferenceError:42:Invalid left hand side for assignment null-- ^ -ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment +ReferenceError:49:Invalid left hand side for assignment ++null ^ -ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment +ReferenceError:56:Invalid left hand side for assignment --null ^ diff --git a/nashorn/test/script/basic/NASHORN-98.js b/nashorn/test/script/basic/NASHORN-98.js index 3e50cf56e6c..9e341e0c3c8 100644 --- a/nashorn/test/script/basic/NASHORN-98.js +++ b/nashorn/test/script/basic/NASHORN-98.js @@ -34,7 +34,7 @@ try { if (! (e instanceof SyntaxError)) { fail("syntax error expected here got " + e); } - print(e.toString().replace(/\\/g, '/')); + printError(e); } try { @@ -43,5 +43,5 @@ try { if (! (e instanceof SyntaxError)) { fail("syntax error expected here got " + e); } - print(e.toString().replace(/\\/g, '/')); + printError(e); } diff --git a/nashorn/test/script/basic/NASHORN-98.js.EXPECTED b/nashorn/test/script/basic/NASHORN-98.js.EXPECTED index 93a89364703..a43935bfec4 100644 --- a/nashorn/test/script/basic/NASHORN-98.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-98.js.EXPECTED @@ -1,6 +1,6 @@ -SyntaxError: test/script/basic/NASHORN-98.js#32:1:13 Expected comma but found decimal +SyntaxError:32:Expected comma but found decimal var x = [ 23 34 ] ^ -SyntaxError: test/script/basic/NASHORN-98.js#41:1:18 Expected comma but found ident +SyntaxError:41:Expected comma but found ident var x = { foo: 33 bar: 'hello' } ^ diff --git a/nashorn/test/script/basic/eval.js b/nashorn/test/script/basic/eval.js index bd63068ca68..3d66c028588 100644 --- a/nashorn/test/script/basic/eval.js +++ b/nashorn/test/script/basic/eval.js @@ -69,5 +69,5 @@ try { eval("print('hello)"); } catch (e) { print("is syntax error? " + (e instanceof SyntaxError)); - print(e.toString().replace(/\\/g, '/')); + printError(e); } diff --git a/nashorn/test/script/basic/eval.js.EXPECTED b/nashorn/test/script/basic/eval.js.EXPECTED index 3ab2f3dab51..7fe97ef6149 100644 --- a/nashorn/test/script/basic/eval.js.EXPECTED +++ b/nashorn/test/script/basic/eval.js.EXPECTED @@ -10,6 +10,6 @@ eval.length 1 100 3300 is syntax error? true -SyntaxError: test/script/basic/eval.js#69:1:13 Missing close quote +SyntaxError:69:Missing close quote print('hello) ^ From 8cf473803150b678101dbd99590d0fc1c4c530c5 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 10 Oct 2013 13:17:57 +0200 Subject: [PATCH 039/152] 8026248: importClass has to be a varargs function Reviewed-by: jlaskey, hannesw --- .../runtime/resources/mozilla_compat.js | 24 ++++++--- nashorn/test/script/basic/JDK-8026248.js | 51 +++++++++++++++++++ .../test/script/basic/JDK-8026248.js.EXPECTED | 10 ++++ 3 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026248.js create mode 100644 nashorn/test/script/basic/JDK-8026248.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js index 6b934ad4b00..f54dcfb8bf0 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -41,7 +41,12 @@ Object.defineProperty(this, "JavaAdapter", { } }); + // importPackage +// avoid unnecessary chaining of __noSuchProperty__ again +// in case user loads this script more than once. +if (typeof importPackage == 'undefined') { + Object.defineProperty(this, "importPackage", { configurable: true, enumerable: false, writable: true, value: (function() { @@ -91,6 +96,8 @@ Object.defineProperty(this, "importPackage", { })() }); +} + // Object.prototype.__defineGetter__ Object.defineProperty(Object.prototype, "__defineGetter__", { configurable: true, enumerable: false, writable: true, @@ -344,13 +351,16 @@ Object.defineProperty(String.prototype, "sup", { // Rhino: global.importClass Object.defineProperty(this, "importClass", { configurable: true, enumerable: false, writable: true, - value: function(clazz) { - if (Java.isType(clazz)) { - var className = Java.typeName(clazz); - var simpleName = className.substring(className.lastIndexOf('.') + 1); - this[simpleName] = clazz; - } else { - throw new TypeError(clazz + " is not a Java class"); + value: function() { + for (var arg in arguments) { + var clazz = arguments[arg]; + if (Java.isType(clazz)) { + var className = Java.typeName(clazz); + var simpleName = className.substring(className.lastIndexOf('.') + 1); + this[simpleName] = clazz; + } else { + throw new TypeError(clazz + " is not a Java class"); + } } } }); diff --git a/nashorn/test/script/basic/JDK-8026248.js b/nashorn/test/script/basic/JDK-8026248.js new file mode 100644 index 00000000000..e54d338314d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026248.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026248: importClass has to be a varargs function + * + * @test + * @run + */ + +load('nashorn:mozilla_compat.js') + +importClass(java.io.File, java.io.InputStream) + +print(File) +print(InputStream) + +importClass(java.util.Map, java.util.HashMap, java.io.PrintStream) + +print(HashMap) +print(Map) +print(PrintStream) + +importClass.call(this, java.util.Collections, java.util.List); +print(Collections) +print(List) + +importClass.apply(this, [ java.util.Queue, java.math.BigInteger, java.math.BigDecimal ]); +print(Queue) +print(BigInteger) +print(BigDecimal) diff --git a/nashorn/test/script/basic/JDK-8026248.js.EXPECTED b/nashorn/test/script/basic/JDK-8026248.js.EXPECTED new file mode 100644 index 00000000000..361b8e17bdb --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026248.js.EXPECTED @@ -0,0 +1,10 @@ +[JavaClass java.io.File] +[JavaClass java.io.InputStream] +[JavaClass java.util.HashMap] +[JavaClass java.util.Map] +[JavaClass java.io.PrintStream] +[JavaClass java.util.Collections] +[JavaClass java.util.List] +[JavaClass java.util.Queue] +[JavaClass java.math.BigInteger] +[JavaClass java.math.BigDecimal] From a577bf41545178e2d9d5f9796acfd1ddd497c67f Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 10 Oct 2013 14:43:22 +0200 Subject: [PATCH 040/152] 8026162: "this" in SAM adapter functions is wrong Reviewed-by: jlaskey, hannesw --- .../internal/runtime/ScriptFunction.java | 2 +- .../linker/JavaAdapterBytecodeGenerator.java | 2 +- .../runtime/linker/JavaAdapterServices.java | 5 +- nashorn/test/script/basic/JDK-8026162.js | 48 +++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026162.js diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java index 14aab7560e6..72658df07b8 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java @@ -326,7 +326,7 @@ public abstract class ScriptFunction extends ScriptObject { * @param self self reference * @return bound invoke handle */ - public final MethodHandle getBoundInvokeHandle(final ScriptObject self) { + public final MethodHandle getBoundInvokeHandle(final Object self) { return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker()), self); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java index 8ebdc810916..5b8d4cfe3f0 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java @@ -93,7 +93,7 @@ import sun.reflect.CallerSensitive; * its last argument preceded by original constructor arguments. This constructor will use the passed function as the * implementation for all abstract methods. For consistency, any concrete methods sharing the single abstract method * name will also be overridden by the function. When methods on the adapter instance are invoked, the ScriptFunction is - * invoked with {@code null} as its "this". + * invoked with global or UNDEFINED as its "this" depending whether the function is non-strict or not. * *
  • * If the adapter being generated can have class-level overrides, constructors taking same arguments as the superclass diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java index 6614304f112..06ae1b1109b 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java @@ -29,6 +29,7 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -53,8 +54,8 @@ public final class JavaAdapterServices { * @return the appropriately adapted method handle for invoking the script function. */ public static MethodHandle getHandle(final ScriptFunction fn, final MethodType type) { - // JS "this" will be null for SAMs - return adaptHandle(fn.getBoundInvokeHandle(null), type); + // JS "this" will be global object or undefined depending on if 'fn' is strict or not + return adaptHandle(fn.getBoundInvokeHandle(fn.isStrict()? ScriptRuntime.UNDEFINED : Context.getGlobal()), type); } /** diff --git a/nashorn/test/script/basic/JDK-8026162.js b/nashorn/test/script/basic/JDK-8026162.js new file mode 100644 index 00000000000..ccd6ee71604 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026162.js @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026162: "this" in SAM adapter functions is wrong + * + * @test + * @run + */ + +var global = this; + +new java.lang.Runnable( + function func() { + if (this !== global) { + fail("Expected 'this' to be global instance"); + } + } +).run(); + +new java.lang.Runnable( + function func() { + 'use strict'; + if (typeof this != 'undefined') { + fail("Expected 'undefined' to be global instance"); + } + } +).run(); From aef0d74e96d9c11d4b1f31dd55b50848b35b5b5d Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Thu, 10 Oct 2013 15:44:12 +0200 Subject: [PATCH 041/152] 8023014: CodeSweeperSweepNoFlushTest.java fails with HS crash Ensure ensure correct initialization of compiler runtime Reviewed-by: kvn, twisti --- hotspot/src/share/vm/c1/c1_Compiler.cpp | 56 ++-- hotspot/src/share/vm/c1/c1_Compiler.hpp | 13 +- hotspot/src/share/vm/code/codeBlob.cpp | 14 +- hotspot/src/share/vm/code/codeBlob.hpp | 3 +- .../share/vm/compiler/abstractCompiler.cpp | 65 ++-- .../share/vm/compiler/abstractCompiler.hpp | 36 ++- .../src/share/vm/compiler/compileBroker.cpp | 280 ++++++++++++------ .../src/share/vm/compiler/compileBroker.hpp | 30 +- hotspot/src/share/vm/opto/c2compiler.cpp | 37 +-- hotspot/src/share/vm/opto/c2compiler.hpp | 11 +- hotspot/src/share/vm/opto/runtime.cpp | 9 +- hotspot/src/share/vm/opto/runtime.hpp | 6 +- hotspot/src/share/vm/runtime/thread.cpp | 9 +- hotspot/src/share/vm/runtime/thread.hpp | 29 +- hotspot/src/share/vm/runtime/vmStructs.cpp | 1 - hotspot/src/share/vm/shark/sharkCompiler.cpp | 5 +- hotspot/src/share/vm/shark/sharkCompiler.hpp | 4 - .../startup/SmallCodeCacheStartup.java | 43 +++ 18 files changed, 386 insertions(+), 265 deletions(-) create mode 100644 hotspot/test/compiler/startup/SmallCodeCacheStartup.java diff --git a/hotspot/src/share/vm/c1/c1_Compiler.cpp b/hotspot/src/share/vm/c1/c1_Compiler.cpp index ecace4dad07..0fb723c8a95 100644 --- a/hotspot/src/share/vm/c1/c1_Compiler.cpp +++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp @@ -42,26 +42,16 @@ #include "runtime/interfaceSupport.hpp" #include "runtime/sharedRuntime.hpp" -volatile int Compiler::_runtimes = uninitialized; -Compiler::Compiler() { -} +Compiler::Compiler () {} - -Compiler::~Compiler() { - Unimplemented(); -} - - -void Compiler::initialize_all() { +void Compiler::init_c1_runtime() { BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); Arena* arena = new (mtCompiler) Arena(); Runtime1::initialize(buffer_blob); FrameMap::initialize(); // initialize data structures ValueType::initialize(arena); - // Instruction::initialize(); - // BlockBegin::initialize(); GraphBuilder::initialize(); // note: to use more than one instance of LinearScan at a time this function call has to // be moved somewhere outside of this constructor: @@ -70,32 +60,33 @@ void Compiler::initialize_all() { void Compiler::initialize() { - if (_runtimes != initialized) { - initialize_runtimes( initialize_all, &_runtimes); + // Buffer blob must be allocated per C1 compiler thread at startup + BufferBlob* buffer_blob = init_buffer_blob(); + + if (should_perform_init()) { + if (buffer_blob == NULL) { + // When we come here we are in state 'initializing'; entire C1 compilation + // can be shut down. + set_state(failed); + } else { + init_c1_runtime(); + set_state(initialized); + } } - mark_initialized(); } - -BufferBlob* Compiler::get_buffer_blob(ciEnv* env) { +BufferBlob* Compiler::init_buffer_blob() { // Allocate buffer blob once at startup since allocation for each // compilation seems to be too expensive (at least on Intel win32). - BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); - if (buffer_blob != NULL) { - return buffer_blob; - } + assert (CompilerThread::current()->get_buffer_blob() == NULL, "Should initialize only once"); // setup CodeBuffer. Preallocate a BufferBlob of size // NMethodSizeLimit plus some extra space for constants. int code_buffer_size = Compilation::desired_max_code_buffer_size() + Compilation::desired_max_constant_size(); - buffer_blob = BufferBlob::create("Compiler1 temporary CodeBuffer", - code_buffer_size); - if (buffer_blob == NULL) { - CompileBroker::handle_full_code_cache(); - env->record_failure("CodeCache is full"); - } else { + BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size); + if (buffer_blob != NULL) { CompilerThread::current()->set_buffer_blob(buffer_blob); } @@ -104,15 +95,8 @@ BufferBlob* Compiler::get_buffer_blob(ciEnv* env) { void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) { - BufferBlob* buffer_blob = Compiler::get_buffer_blob(env); - if (buffer_blob == NULL) { - return; - } - - if (!is_initialized()) { - initialize(); - } - + BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); + assert(buffer_blob != NULL, "Must exist"); // invoke compilation { // We are nested here because we need for the destructor diff --git a/hotspot/src/share/vm/c1/c1_Compiler.hpp b/hotspot/src/share/vm/c1/c1_Compiler.hpp index 6e209d0034f..fe95c8cd780 100644 --- a/hotspot/src/share/vm/c1/c1_Compiler.hpp +++ b/hotspot/src/share/vm/c1/c1_Compiler.hpp @@ -30,11 +30,9 @@ // There is one instance of the Compiler per CompilerThread. class Compiler: public AbstractCompiler { - private: - - // Tracks whether runtime has been initialized - static volatile int _runtimes; + static void init_c1_runtime(); + BufferBlob* init_buffer_blob(); public: // Creation @@ -46,19 +44,12 @@ class Compiler: public AbstractCompiler { virtual bool is_c1() { return true; }; - BufferBlob* get_buffer_blob(ciEnv* env); - // Missing feature tests virtual bool supports_native() { return true; } virtual bool supports_osr () { return true; } - // Customization - virtual bool needs_adapters () { return false; } - virtual bool needs_stubs () { return false; } - // Initialization virtual void initialize(); - static void initialize_all(); // Compilation entry point for methods virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci); diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp index e377f893ee1..141bbae007b 100644 --- a/hotspot/src/share/vm/code/codeBlob.cpp +++ b/hotspot/src/share/vm/code/codeBlob.cpp @@ -245,8 +245,8 @@ BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) { } -void* BufferBlob::operator new(size_t s, unsigned size) throw() { - void* p = CodeCache::allocate(size); +void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() { + void* p = CodeCache::allocate(size, is_critical); return p; } @@ -277,7 +277,10 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { unsigned int size = allocation_size(cb, sizeof(AdapterBlob)); { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - blob = new (size) AdapterBlob(size, cb); + // The parameter 'true' indicates a critical memory allocation. + // This means that CodeCacheMinimumFreeSpace is used, if necessary + const bool is_critical = true; + blob = new (size, is_critical) AdapterBlob(size, cb); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); @@ -299,7 +302,10 @@ MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) { size += round_to(buffer_size, oopSize); { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - blob = new (size) MethodHandlesAdapterBlob(size); + // The parameter 'true' indicates a critical memory allocation. + // This means that CodeCacheMinimumFreeSpace is used, if necessary + const bool is_critical = true; + blob = new (size, is_critical) MethodHandlesAdapterBlob(size); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp index 6587b2d2e51..db270f135ce 100644 --- a/hotspot/src/share/vm/code/codeBlob.hpp +++ b/hotspot/src/share/vm/code/codeBlob.hpp @@ -209,7 +209,7 @@ class BufferBlob: public CodeBlob { BufferBlob(const char* name, int size); BufferBlob(const char* name, int size, CodeBuffer* cb); - void* operator new(size_t s, unsigned size) throw(); + void* operator new(size_t s, unsigned size, bool is_critical = false) throw(); public: // Creation @@ -253,7 +253,6 @@ public: class MethodHandlesAdapterBlob: public BufferBlob { private: MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {} - MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {} public: // Creation diff --git a/hotspot/src/share/vm/compiler/abstractCompiler.cpp b/hotspot/src/share/vm/compiler/abstractCompiler.cpp index 942c168e512..3f452a1b53b 100644 --- a/hotspot/src/share/vm/compiler/abstractCompiler.cpp +++ b/hotspot/src/share/vm/compiler/abstractCompiler.cpp @@ -24,41 +24,42 @@ #include "precompiled.hpp" #include "compiler/abstractCompiler.hpp" +#include "compiler/compileBroker.hpp" #include "runtime/mutexLocker.hpp" -void AbstractCompiler::initialize_runtimes(initializer f, volatile int* state) { - if (*state != initialized) { - // We are thread in native here... - CompilerThread* thread = CompilerThread::current(); - bool do_initialization = false; - { - ThreadInVMfromNative tv(thread); - ResetNoHandleMark rnhm; - MutexLocker only_one(CompileThread_lock, thread); - if ( *state == uninitialized) { - do_initialization = true; - *state = initializing; - } else { - while (*state == initializing ) { - CompileThread_lock->wait(); - } +bool AbstractCompiler::should_perform_init() { + if (_compiler_state != initialized) { + MutexLocker only_one(CompileThread_lock); + + if (_compiler_state == uninitialized) { + _compiler_state = initializing; + return true; + } else { + while (_compiler_state == initializing) { + CompileThread_lock->wait(); } } - if (do_initialization) { - // We can not hold any locks here since JVMTI events may call agents - - // Compiler(s) run as native - - (*f)(); - - // To in_vm so we can use the lock - - ThreadInVMfromNative tv(thread); - ResetNoHandleMark rnhm; - MutexLocker only_one(CompileThread_lock, thread); - assert(*state == initializing, "wrong state"); - *state = initialized; - CompileThread_lock->notify_all(); - } } + return false; +} + +bool AbstractCompiler::should_perform_shutdown() { + // Since this method can be called by multiple threads, the lock ensures atomicity of + // decrementing '_num_compiler_threads' and the following operations. + MutexLocker only_one(CompileThread_lock); + _num_compiler_threads--; + assert (CompileBroker::is_compilation_disabled_forever(), "Must be set, otherwise thread waits forever"); + + // Only the last thread will perform shutdown operations + if (_num_compiler_threads == 0) { + return true; + } + return false; +} + +void AbstractCompiler::set_state(int state) { + // Ensure that ste is only set by one thread at a time + MutexLocker only_one(CompileThread_lock); + _compiler_state = state; + CompileThread_lock->notify_all(); } diff --git a/hotspot/src/share/vm/compiler/abstractCompiler.hpp b/hotspot/src/share/vm/compiler/abstractCompiler.hpp index 96453e7d9ba..d150e8e8085 100644 --- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp +++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp @@ -27,22 +27,25 @@ #include "ci/compilerInterface.hpp" -typedef void (*initializer)(void); - class AbstractCompiler : public CHeapObj { private: - bool _is_initialized; // Mark whether compiler object is initialized + volatile int _num_compiler_threads; protected: + volatile int _compiler_state; // Used for tracking global state of compiler runtime initialization - enum { uninitialized, initializing, initialized }; + enum { uninitialized, initializing, initialized, failed, shut_down }; - // This method will call the initialization method "f" once (per compiler class/subclass) - // and do so without holding any locks - void initialize_runtimes(initializer f, volatile int* state); + // This method returns true for the first compiler thread that reaches that methods. + // This thread will initialize the compiler runtime. + bool should_perform_init(); public: - AbstractCompiler() : _is_initialized(false) {} + AbstractCompiler() : _compiler_state(uninitialized), _num_compiler_threads(0) {} + + // This function determines the compiler thread that will perform the + // shutdown of the corresponding compiler runtime. + bool should_perform_shutdown(); // Name of this compiler virtual const char* name() = 0; @@ -74,17 +77,18 @@ class AbstractCompiler : public CHeapObj { #endif // TIERED // Customization - virtual bool needs_stubs () = 0; + virtual void initialize () = 0; - void mark_initialized() { _is_initialized = true; } - bool is_initialized() { return _is_initialized; } - - virtual void initialize() = 0; + void set_num_compiler_threads(int num) { _num_compiler_threads = num; } + int num_compiler_threads() { return _num_compiler_threads; } + // Get/set state of compiler objects + bool is_initialized() { return _compiler_state == initialized; } + bool is_failed () { return _compiler_state == failed;} + void set_state (int state); + void set_shut_down () { set_state(shut_down); } // Compilation entry point for methods - virtual void compile_method(ciEnv* env, - ciMethod* target, - int entry_bci) { + virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci) { ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 8040224f77e..cc860613a57 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -186,7 +186,7 @@ CompileQueue* CompileBroker::_c2_method_queue = NULL; CompileQueue* CompileBroker::_c1_method_queue = NULL; CompileTask* CompileBroker::_task_free_list = NULL; -GrowableArray* CompileBroker::_method_threads = NULL; +GrowableArray* CompileBroker::_compiler_threads = NULL; class CompilationLog : public StringEventLog { @@ -587,9 +587,6 @@ void CompileTask::log_task_done(CompileLog* log) { -// ------------------------------------------------------------------ -// CompileQueue::add -// // Add a CompileTask to a CompileQueue void CompileQueue::add(CompileTask* task) { assert(lock()->owned_by_self(), "must own lock"); @@ -626,6 +623,16 @@ void CompileQueue::add(CompileTask* task) { lock()->notify_all(); } +void CompileQueue::delete_all() { + assert(lock()->owned_by_self(), "must own lock"); + if (_first != NULL) { + for (CompileTask* task = _first; task != NULL; task = task->next()) { + delete task; + } + _first = NULL; + } +} + // ------------------------------------------------------------------ // CompileQueue::get // @@ -640,6 +647,11 @@ CompileTask* CompileQueue::get() { // case we perform code cache sweeps to free memory such that we can re-enable // compilation. while (_first == NULL) { + // Exit loop if compilation is disabled forever + if (CompileBroker::is_compilation_disabled_forever()) { + return NULL; + } + if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) { // Wait a certain amount of time to possibly do another sweep. // We must wait until stack scanning has happened so that we can @@ -664,9 +676,17 @@ CompileTask* CompileQueue::get() { // remains unchanged. This behavior is desired, since we want to keep // the stable state, i.e., we do not want to evict methods from the // code cache if it is unnecessary. - lock()->wait(); + // We need a timed wait here, since compiler threads can exit if compilation + // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads + // is not critical and we do not want idle compiler threads to wake up too often. + lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000); } } + + if (CompileBroker::is_compilation_disabled_forever()) { + return NULL; + } + CompileTask* task = CompilationPolicy::policy()->select_task(this); remove(task); return task; @@ -891,10 +911,8 @@ void CompileBroker::compilation_init() { } - -// ------------------------------------------------------------------ -// CompileBroker::make_compiler_thread -CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) { +CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, + AbstractCompiler* comp, TRAPS) { CompilerThread* compiler_thread = NULL; Klass* k = @@ -961,6 +979,7 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue java_lang_Thread::set_daemon(thread_oop()); compiler_thread->set_threadObj(thread_oop()); + compiler_thread->set_compiler(comp); Threads::add(compiler_thread); Thread::start(compiler_thread); } @@ -972,25 +991,24 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue } -// ------------------------------------------------------------------ -// CompileBroker::init_compiler_threads -// -// Initialize the compilation queue void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) { EXCEPTION_MARK; #if !defined(ZERO) && !defined(SHARK) assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?"); #endif // !ZERO && !SHARK + // Initialize the compilation queue if (c2_compiler_count > 0) { _c2_method_queue = new CompileQueue("C2MethodQueue", MethodCompileQueue_lock); + _compilers[1]->set_num_compiler_threads(c2_compiler_count); } if (c1_compiler_count > 0) { _c1_method_queue = new CompileQueue("C1MethodQueue", MethodCompileQueue_lock); + _compilers[0]->set_num_compiler_threads(c1_compiler_count); } int compiler_count = c1_compiler_count + c2_compiler_count; - _method_threads = + _compiler_threads = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray(compiler_count, true); char name_buffer[256]; @@ -998,21 +1016,22 @@ void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler // Create a name for our thread. sprintf(name_buffer, "C2 CompilerThread%d", i); CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); - CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, CHECK); - _method_threads->append(new_thread); + // Shark and C2 + CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, _compilers[1], CHECK); + _compiler_threads->append(new_thread); } for (int i = c2_compiler_count; i < compiler_count; i++) { // Create a name for our thread. sprintf(name_buffer, "C1 CompilerThread%d", i); CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); - CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, CHECK); - _method_threads->append(new_thread); + // C1 + CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, _compilers[0], CHECK); + _compiler_threads->append(new_thread); } if (UsePerfData) { - PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, - compiler_count, CHECK); + PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK); } } @@ -1028,27 +1047,6 @@ void CompileBroker::mark_on_stack() { } } -// ------------------------------------------------------------------ -// CompileBroker::is_idle -bool CompileBroker::is_idle() { - if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) { - return false; - } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) { - return false; - } else { - int num_threads = _method_threads->length(); - for (int i=0; iat(i)->task() != NULL) { - return false; - } - } - - // No pending or active compilations. - return true; - } -} - - // ------------------------------------------------------------------ // CompileBroker::compile_method // @@ -1551,6 +1549,101 @@ void CompileBroker::wait_for_completion(CompileTask* task) { free_task(task); } +// Initialize compiler thread(s) + compiler object(s). The postcondition +// of this function is that the compiler runtimes are initialized and that +//compiler threads can start compiling. +bool CompileBroker::init_compiler_runtime() { + CompilerThread* thread = CompilerThread::current(); + AbstractCompiler* comp = thread->compiler(); + // Final sanity check - the compiler object must exist + guarantee(comp != NULL, "Compiler object must exist"); + + int system_dictionary_modification_counter; + { + MutexLocker locker(Compile_lock, thread); + system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); + } + + { + // Must switch to native to allocate ci_env + ThreadToNativeFromVM ttn(thread); + ciEnv ci_env(NULL, system_dictionary_modification_counter); + // Cache Jvmti state + ci_env.cache_jvmti_state(); + // Cache DTrace flags + ci_env.cache_dtrace_flags(); + + // Switch back to VM state to do compiler initialization + ThreadInVMfromNative tv(thread); + ResetNoHandleMark rnhm; + + + if (!comp->is_shark()) { + // Perform per-thread and global initializations + comp->initialize(); + } + } + + if (comp->is_failed()) { + disable_compilation_forever(); + // If compiler initialization failed, no compiler thread that is specific to a + // particular compiler runtime will ever start to compile methods. + + shutdown_compiler_runtime(comp, thread); + return false; + } + + // C1 specific check + if (comp->is_c1() && (thread->get_buffer_blob() == NULL)) { + warning("Initialization of %s thread failed (no space to run compilers)", thread->name()); + return false; + } + + return true; +} + +// If C1 and/or C2 initialization failed, we shut down all compilation. +// We do this to keep things simple. This can be changed if it ever turns out to be +// a problem. +void CompileBroker::shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread) { + // Free buffer blob, if allocated + if (thread->get_buffer_blob() != NULL) { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::free(thread->get_buffer_blob()); + } + + if (comp->should_perform_shutdown()) { + // There are two reasons for shutting down the compiler + // 1) compiler runtime initialization failed + // 2) The code cache is full and the following flag is set: -XX:-UseCodeCacheFlushing + warning("Shutting down compiler %s (no space to run compilers)", comp->name()); + + // Only one thread per compiler runtime object enters here + // Set state to shut down + comp->set_shut_down(); + + MutexLocker mu(MethodCompileQueue_lock, thread); + CompileQueue* queue; + if (_c1_method_queue != NULL) { + _c1_method_queue->delete_all(); + queue = _c1_method_queue; + _c1_method_queue = NULL; + delete _c1_method_queue; + } + + if (_c2_method_queue != NULL) { + _c2_method_queue->delete_all(); + queue = _c2_method_queue; + _c2_method_queue = NULL; + delete _c2_method_queue; + } + + // We could delete compiler runtimes also. However, there are references to + // the compiler runtime(s) (e.g., nmethod::is_compiled_by_c1()) which then + // fail. This can be done later if necessary. + } +} + // ------------------------------------------------------------------ // CompileBroker::compiler_thread_loop // @@ -1558,7 +1651,6 @@ void CompileBroker::wait_for_completion(CompileTask* task) { void CompileBroker::compiler_thread_loop() { CompilerThread* thread = CompilerThread::current(); CompileQueue* queue = thread->queue(); - // For the thread that initializes the ciObjectFactory // this resource mark holds all the shared objects ResourceMark rm; @@ -1587,64 +1679,77 @@ void CompileBroker::compiler_thread_loop() { log->end_elem(); } - while (true) { - { - // We need this HandleMark to avoid leaking VM handles. - HandleMark hm(thread); + // If compiler thread/runtime initialization fails, exit the compiler thread + if (!init_compiler_runtime()) { + return; + } - if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { - // the code cache is really full - handle_full_code_cache(); - } + // Poll for new compilation tasks as long as the JVM runs. Compilation + // should only be disabled if something went wrong while initializing the + // compiler runtimes. This, in turn, should not happen. The only known case + // when compiler runtime initialization fails is if there is not enough free + // space in the code cache to generate the necessary stubs, etc. + while (!is_compilation_disabled_forever()) { + // We need this HandleMark to avoid leaking VM handles. + HandleMark hm(thread); - CompileTask* task = queue->get(); + if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { + // the code cache is really full + handle_full_code_cache(); + } - // Give compiler threads an extra quanta. They tend to be bursty and - // this helps the compiler to finish up the job. - if( CompilerThreadHintNoPreempt ) - os::hint_no_preempt(); + CompileTask* task = queue->get(); + if (task == NULL) { + continue; + } - // trace per thread time and compile statistics - CompilerCounters* counters = ((CompilerThread*)thread)->counters(); - PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); + // Give compiler threads an extra quanta. They tend to be bursty and + // this helps the compiler to finish up the job. + if( CompilerThreadHintNoPreempt ) + os::hint_no_preempt(); - // Assign the task to the current thread. Mark this compilation - // thread as active for the profiler. - CompileTaskWrapper ctw(task); - nmethodLocker result_handle; // (handle for the nmethod produced by this task) - task->set_code_handle(&result_handle); - methodHandle method(thread, task->method()); + // trace per thread time and compile statistics + CompilerCounters* counters = ((CompilerThread*)thread)->counters(); + PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); - // Never compile a method if breakpoints are present in it - if (method()->number_of_breakpoints() == 0) { - // Compile the method. - if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) { + // Assign the task to the current thread. Mark this compilation + // thread as active for the profiler. + CompileTaskWrapper ctw(task); + nmethodLocker result_handle; // (handle for the nmethod produced by this task) + task->set_code_handle(&result_handle); + methodHandle method(thread, task->method()); + + // Never compile a method if breakpoints are present in it + if (method()->number_of_breakpoints() == 0) { + // Compile the method. + if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) { #ifdef COMPILER1 - // Allow repeating compilations for the purpose of benchmarking - // compile speed. This is not useful for customers. - if (CompilationRepeat != 0) { - int compile_count = CompilationRepeat; - while (compile_count > 0) { - invoke_compiler_on_method(task); - nmethod* nm = method->code(); - if (nm != NULL) { - nm->make_zombie(); - method->clear_code(); - } - compile_count--; + // Allow repeating compilations for the purpose of benchmarking + // compile speed. This is not useful for customers. + if (CompilationRepeat != 0) { + int compile_count = CompilationRepeat; + while (compile_count > 0) { + invoke_compiler_on_method(task); + nmethod* nm = method->code(); + if (nm != NULL) { + nm->make_zombie(); + method->clear_code(); } + compile_count--; } -#endif /* COMPILER1 */ - invoke_compiler_on_method(task); - } else { - // After compilation is disabled, remove remaining methods from queue - method->clear_queued_for_compilation(); } +#endif /* COMPILER1 */ + invoke_compiler_on_method(task); + } else { + // After compilation is disabled, remove remaining methods from queue + method->clear_queued_for_compilation(); } } } -} + // Shut down compiler runtime + shutdown_compiler_runtime(thread->compiler(), thread); +} // ------------------------------------------------------------------ // CompileBroker::init_compiler_thread_log @@ -1960,8 +2065,7 @@ void CompileBroker::handle_full_code_cache() { NMethodSweeper::possibly_sweep(); } } else { - UseCompiler = false; - AlwaysCompileLoopMethods = false; + disable_compilation_forever(); } } codecache_print(/* detailed= */ true); diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp index f336497a31d..19beeec9fb4 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.hpp +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp @@ -213,8 +213,12 @@ class CompileQueue : public CHeapObj { // Redefine Classes support void mark_on_stack(); - + void delete_all(); void print(); + + ~CompileQueue() { + assert (is_empty(), " Compile Queue must be empty"); + } }; // CompileTaskWrapper @@ -266,7 +270,7 @@ class CompileBroker: AllStatic { static CompileQueue* _c1_method_queue; static CompileTask* _task_free_list; - static GrowableArray* _method_threads; + static GrowableArray* _compiler_threads; // performance counters static PerfCounter* _perf_total_compilation; @@ -311,7 +315,7 @@ class CompileBroker: AllStatic { static int _sum_nmethod_code_size; static long _peak_compilation_time; - static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS); + static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS); static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); @@ -351,6 +355,9 @@ class CompileBroker: AllStatic { if (is_c1_compile(comp_level)) return _c1_method_queue; return NULL; } + static bool init_compiler_runtime(); + static void shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread); + public: enum { // The entry bci used for non-OSR compilations. @@ -378,9 +385,7 @@ class CompileBroker: AllStatic { const char* comment, Thread* thread); static void compiler_thread_loop(); - static uint get_compilation_id() { return _compilation_id; } - static bool is_idle(); // Set _should_block. // Call this from the VM, with Threads_lock held and a safepoint requested. @@ -391,8 +396,9 @@ class CompileBroker: AllStatic { enum { // Flags for toggling compiler activity - stop_compilation = 0, - run_compilation = 1 + stop_compilation = 0, + run_compilation = 1, + shutdown_compilaton = 2 }; static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); } @@ -401,6 +407,16 @@ class CompileBroker: AllStatic { jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state); return (old == (1-new_state)); } + + static void disable_compilation_forever() { + UseCompiler = false; + AlwaysCompileLoopMethods = false; + Atomic::xchg(shutdown_compilaton, &_should_compile_new_jobs); + } + + static bool is_compilation_disabled_forever() { + return _should_compile_new_jobs == shutdown_compilaton; + } static void handle_full_code_cache(); // Return total compilation ticks diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp index 85f30a5ac1e..91653bd3ce3 100644 --- a/hotspot/src/share/vm/opto/c2compiler.cpp +++ b/hotspot/src/share/vm/opto/c2compiler.cpp @@ -44,9 +44,6 @@ # include "adfiles/ad_ppc.hpp" #endif - -volatile int C2Compiler::_runtimes = uninitialized; - // register information defined by ADLC extern const char register_save_policy[]; extern const int register_save_type[]; @@ -57,7 +54,7 @@ const char* C2Compiler::retry_no_subsuming_loads() { const char* C2Compiler::retry_no_escape_analysis() { return "retry without escape analysis"; } -void C2Compiler::initialize_runtime() { +bool C2Compiler::init_c2_runtime() { // Check assumptions used while running ADLC Compile::adlc_verification(); @@ -90,41 +87,31 @@ void C2Compiler::initialize_runtime() { CompilerThread* thread = CompilerThread::current(); - HandleMark handle_mark(thread); - - OptoRuntime::generate(thread->env()); - + HandleMark handle_mark(thread); + return OptoRuntime::generate(thread->env()); } void C2Compiler::initialize() { - - // This method can only be called once per C2Compiler object // The first compiler thread that gets here will initialize the - // small amount of global state (and runtime stubs) that c2 needs. + // small amount of global state (and runtime stubs) that C2 needs. // There is a race possible once at startup and then we're fine // Note that this is being called from a compiler thread not the // main startup thread. - - if (_runtimes != initialized) { - initialize_runtimes( initialize_runtime, &_runtimes); + if (should_perform_init()) { + bool successful = C2Compiler::init_c2_runtime(); + int new_state = (successful) ? initialized : failed; + set_state(new_state); } - - // Mark this compiler object as ready to roll - mark_initialized(); } -void C2Compiler::compile_method(ciEnv* env, - ciMethod* target, - int entry_bci) { - if (!is_initialized()) { - initialize(); - } +void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) { + assert(is_initialized(), "Compiler thread must be initialized"); + bool subsume_loads = SubsumeLoads; - bool do_escape_analysis = DoEscapeAnalysis && - !env->jvmti_can_access_local_variables(); + bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); bool eliminate_boxing = EliminateAutoBox; while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions. diff --git a/hotspot/src/share/vm/opto/c2compiler.hpp b/hotspot/src/share/vm/opto/c2compiler.hpp index c25f2ea926a..48ccc1b5105 100644 --- a/hotspot/src/share/vm/opto/c2compiler.hpp +++ b/hotspot/src/share/vm/opto/c2compiler.hpp @@ -28,24 +28,17 @@ #include "compiler/abstractCompiler.hpp" class C2Compiler : public AbstractCompiler { -private: - - static void initialize_runtime(); + private: + static bool init_c2_runtime(); public: // Name const char *name() { return "C2"; } - static volatile int _runtimes; - #ifdef TIERED virtual bool is_c2() { return true; }; #endif // TIERED - // Customization - bool needs_adapters () { return true; } - bool needs_stubs () { return true; } - void initialize(); // Compilation entry point for methods diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index 173a735c9ba..6e09cb7dff9 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -138,9 +138,10 @@ static bool check_compiled_frame(JavaThread* thread) { #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \ - var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc) + var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc); \ + if (var == NULL) { return false; } -void OptoRuntime::generate(ciEnv* env) { +bool OptoRuntime::generate(ciEnv* env) { generate_exception_blob(); @@ -158,7 +159,7 @@ void OptoRuntime::generate(ciEnv* env) { gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true , false, false); gen(env, _g1_wb_pre_Java , g1_wb_pre_Type , SharedRuntime::g1_wb_pre , 0 , false, false, false); gen(env, _g1_wb_post_Java , g1_wb_post_Type , SharedRuntime::g1_wb_post , 0 , false, false, false); - gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C , 0 , false, false, false); + gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false, false); gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , false, true ); gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false); @@ -168,7 +169,7 @@ void OptoRuntime::generate(ciEnv* env) { gen(env, _zap_dead_Java_locals_Java , zap_dead_locals_Type , zap_dead_Java_locals_C , 0 , false, true , false ); gen(env, _zap_dead_native_locals_Java , zap_dead_locals_Type , zap_dead_native_locals_C , 0 , false, true , false ); # endif - + return true; } #undef gen diff --git a/hotspot/src/share/vm/opto/runtime.hpp b/hotspot/src/share/vm/opto/runtime.hpp index b3f7ff4cb1a..aecb97f6572 100644 --- a/hotspot/src/share/vm/opto/runtime.hpp +++ b/hotspot/src/share/vm/opto/runtime.hpp @@ -203,8 +203,10 @@ private: static bool is_callee_saved_register(MachRegisterNumbers reg); - // One time only generate runtime code stubs - static void generate(ciEnv* env); + // One time only generate runtime code stubs. Returns true + // when runtime stubs have been generated successfully and + // false otherwise. + static bool generate(ciEnv* env); // Returns the name of a stub static const char* stub_name(address entry); diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 0e4295bc698..f645be31d80 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1454,7 +1454,6 @@ void JavaThread::initialize() { _interp_only_mode = 0; _special_runtime_exit_condition = _no_async_condition; _pending_async_exception = NULL; - _is_compiling = false; _thread_stat = NULL; _thread_stat = new ThreadStatistics(); _blocked_on_compilation = false; @@ -1815,7 +1814,8 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) { // Call Thread.exit(). We try 3 times in case we got another Thread.stop during // the execution of the method. If that is not enough, then we don't really care. Thread.stop // is deprecated anyhow. - { int count = 3; + if (!is_Compiler_thread()) { + int count = 3; while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) { EXCEPTION_MARK; JavaValue result(T_VOID); @@ -1828,7 +1828,6 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) { CLEAR_PENDING_EXCEPTION; } } - // notify JVMTI if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_end(this); @@ -3239,6 +3238,7 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters) _counters = counters; _buffer_blob = NULL; _scanned_nmethod = NULL; + _compiler = NULL; #ifndef PRODUCT _ideal_graph_printer = NULL; @@ -3255,6 +3255,7 @@ void CompilerThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClos } } + // ======= Threads ======== // The Threads class links together all active threads, and provides @@ -3275,8 +3276,6 @@ bool Threads::_vm_complete = false; // All JavaThreads #define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next()) -void os_stream(); - // All JavaThreads + all non-JavaThreads (i.e., every thread in the system) void Threads::threads_do(ThreadClosure* tc) { assert_locked_or_safepoint(Threads_lock); diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index d9a757eb434..d655df4f1da 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -923,9 +923,6 @@ class JavaThread: public Thread { volatile address _exception_handler_pc; // PC for handler of exception volatile int _is_method_handle_return; // true (== 1) if the current exception PC is a MethodHandle call site. - // support for compilation - bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible) - // support for JNI critical regions jint _jni_active_critical; // count of entries into JNI critical region @@ -1005,10 +1002,6 @@ class JavaThread: public Thread { // Testers virtual bool is_Java_thread() const { return true; } - // compilation - void set_is_compiling(bool f) { _is_compiling = f; } - bool is_compiling() const { return _is_compiling; } - // Thread chain operations JavaThread* next() const { return _next; } void set_next(JavaThread* p) { _next = p; } @@ -1816,13 +1809,14 @@ class CompilerThread : public JavaThread { private: CompilerCounters* _counters; - ciEnv* _env; - CompileLog* _log; - CompileTask* _task; - CompileQueue* _queue; - BufferBlob* _buffer_blob; + ciEnv* _env; + CompileLog* _log; + CompileTask* _task; + CompileQueue* _queue; + BufferBlob* _buffer_blob; - nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper + nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper + AbstractCompiler* _compiler; public: @@ -1834,14 +1828,17 @@ class CompilerThread : public JavaThread { // Hide this compiler thread from external view. bool is_hidden_from_external_view() const { return true; } - CompileQueue* queue() { return _queue; } - CompilerCounters* counters() { return _counters; } + void set_compiler(AbstractCompiler* c) { _compiler = c; } + AbstractCompiler* compiler() const { return _compiler; } + + CompileQueue* queue() const { return _queue; } + CompilerCounters* counters() const { return _counters; } // Get/set the thread's compilation environment. ciEnv* env() { return _env; } void set_env(ciEnv* env) { _env = env; } - BufferBlob* get_buffer_blob() { return _buffer_blob; } + BufferBlob* get_buffer_blob() const { return _buffer_blob; } void set_buffer_blob(BufferBlob* b) { _buffer_blob = b; }; // Get/set the thread's logging information diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index e274b903442..840c1cb0133 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -910,7 +910,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; volatile_nonstatic_field(JavaThread, _exception_oop, oop) \ volatile_nonstatic_field(JavaThread, _exception_pc, address) \ volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \ - nonstatic_field(JavaThread, _is_compiling, bool) \ nonstatic_field(JavaThread, _special_runtime_exit_condition, JavaThread::AsyncRequests) \ nonstatic_field(JavaThread, _saved_exception_pc, address) \ volatile_nonstatic_field(JavaThread, _thread_state, JavaThreadState) \ diff --git a/hotspot/src/share/vm/shark/sharkCompiler.cpp b/hotspot/src/share/vm/shark/sharkCompiler.cpp index cde6bc23e76..211129bc387 100644 --- a/hotspot/src/share/vm/shark/sharkCompiler.cpp +++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp @@ -133,11 +133,10 @@ SharkCompiler::SharkCompiler() exit(1); } - execution_engine()->addModule( - _native_context->module()); + execution_engine()->addModule(_native_context->module()); // All done - mark_initialized(); + set_state(initialized); } void SharkCompiler::initialize() { diff --git a/hotspot/src/share/vm/shark/sharkCompiler.hpp b/hotspot/src/share/vm/shark/sharkCompiler.hpp index 7e530c142aa..12c3cd84c5b 100644 --- a/hotspot/src/share/vm/shark/sharkCompiler.hpp +++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp @@ -50,10 +50,6 @@ class SharkCompiler : public AbstractCompiler { return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()); } - // Customization - bool needs_adapters() { return false; } - bool needs_stubs() { return false; } - // Initialization void initialize(); diff --git a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java new file mode 100644 index 00000000000..74b2b762caa --- /dev/null +++ b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8023014 + * @summary Test ensures that there is no crash when compiler initialization fails + * @library /testlibrary + * + */ +import com.oracle.java.testlibrary.*; + +public class SmallCodeCacheStartup { + public static void main(String[] args) throws Exception { + ProcessBuilder pb; + OutputAnalyzer out; + + pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=3m", "-XX:CICompilerCount=64", "-version"); + out = new OutputAnalyzer(pb.start()); + out.shouldContain("no space to run compiler"); + out.shouldHaveExitValue(0); + } +} From e0aeb3cfb79396c8b0869be89498403e52111312 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Thu, 10 Oct 2013 16:16:20 +0200 Subject: [PATCH 042/152] 8026250: Logging nullpointer bugfix and javadoc warnings Reviewed-by: hannesw, jlaskey, sundar --- .../jdk/nashorn/api/scripting/JSObject.java | 25 +++++---- .../api/scripting/NashornScriptEngine.java | 20 +++---- .../jdk/nashorn/internal/ir/LiteralNode.java | 4 ++ .../jdk/nashorn/internal/objects/Global.java | 4 +- .../nashorn/internal/objects/NativeError.java | 4 +- .../jdk/nashorn/internal/runtime/Context.java | 3 +- .../nashorn/internal/runtime/DebugLogger.java | 14 ++++- .../internal/runtime/GlobalObject.java | 3 +- .../nashorn/internal/runtime/ListAdapter.java | 55 +++++++++++-------- .../internal/runtime/ScriptLoader.java | 1 + .../nashorn/internal/runtime/WithObject.java | 4 ++ 11 files changed, 86 insertions(+), 51 deletions(-) diff --git a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java index 53b5790ee3e..a2d761b4649 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java +++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java @@ -46,7 +46,7 @@ public abstract class JSObject { * @param args arguments to method * @return result of call */ - public Object call(Object thiz, Object... args) { + public Object call(final Object thiz, final Object... args) { throw new UnsupportedOperationException("call"); } @@ -57,7 +57,7 @@ public abstract class JSObject { * @param args arguments to method * @return result of constructor call */ - public Object newObject(Object... args) { + public Object newObject(final Object... args) { throw new UnsupportedOperationException("newObject"); } @@ -67,7 +67,7 @@ public abstract class JSObject { * @param s JavaScript expression to evaluate * @return evaluation result */ - public Object eval(String s) { + public Object eval(final String s) { throw new UnsupportedOperationException("eval"); } @@ -78,7 +78,7 @@ public abstract class JSObject { * @param args arguments to be passed to the member function * @return result of call */ - public Object callMember(String name, Object... args) { + public Object callMember(final String name, final Object... args) { throw new UnsupportedOperationException("call"); } @@ -88,7 +88,7 @@ public abstract class JSObject { * @param name of member * @return member */ - public Object getMember(String name) { + public Object getMember(final String name) { return null; } @@ -98,7 +98,7 @@ public abstract class JSObject { * @param index index slot to retrieve * @return member */ - public Object getSlot(int index) { + public Object getSlot(final int index) { return null; } @@ -108,7 +108,7 @@ public abstract class JSObject { * @param name name of member * @return true if this object has a member of the given name */ - public boolean hasMember(String name) { + public boolean hasMember(final String name) { return false; } @@ -118,7 +118,7 @@ public abstract class JSObject { * @param slot index to check * @return true if this object has a slot */ - public boolean hasSlot(int slot) { + public boolean hasSlot(final int slot) { return false; } @@ -127,7 +127,8 @@ public abstract class JSObject { * * @param name name of the member */ - public void removeMember(String name) { + public void removeMember(final String name) { + //empty } /** @@ -136,7 +137,8 @@ public abstract class JSObject { * @param name name of the member * @param value value of the member */ - public void setMember(String name, Object value) { + public void setMember(final String name, final Object value) { + //empty } /** @@ -145,7 +147,8 @@ public abstract class JSObject { * @param index index of the member slot * @param value value of the member */ - public void setSlot(int index, Object value) { + public void setSlot(final int index, final Object value) { + //empty } // property and value iteration diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 36e79b54bf1..d0fb0c31832 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -285,11 +285,10 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C final URL url = ((URLReader)reader).getURL(); final Charset cs = ((URLReader)reader).getCharset(); return new Source(url.toString(), url, cs); - } else { - return new Source(getScriptName(ctxt), Source.readFully(reader)); } - } catch (final IOException ioExp) { - throw new ScriptException(ioExp); + return new Source(getScriptName(ctxt), Source.readFully(reader)); + } catch (final IOException e) { + throw new ScriptException(e); } } @@ -576,15 +575,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C return new CompiledScript() { @Override public Object eval(final ScriptContext ctxt) throws ScriptException { - final ScriptObject global = getNashornGlobalFrom(ctxt); + final ScriptObject globalObject = getNashornGlobalFrom(ctxt); // Are we running the script in the correct global? - if (func.getScope() == global) { - return evalImpl(func, ctxt, global); - } else { - // ScriptContext with a different global. Compile again! - // Note that we may still hit per-global compilation cache. - return evalImpl(compileImpl(source, ctxt), ctxt, global); + if (func.getScope() == globalObject) { + return evalImpl(func, ctxt, globalObject); } + // ScriptContext with a different global. Compile again! + // Note that we may still hit per-global compilation cache. + return evalImpl(compileImpl(source, ctxt), ctxt, globalObject); } @Override public ScriptEngine getEngine() { diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java index 3d3a1fcbb5d..fcdf55c1725 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java @@ -779,6 +779,10 @@ public abstract class LiteralNode extends Expression implements PropertyKey { return value; } + /** + * Get the array element type as Java format, e.g. [I + * @return array element type + */ public ArrayType getArrayType() { if (elementType.isInteger()) { return Type.INT_ARRAY; diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index 161909bb3f6..f2fd08a5a3d 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -491,8 +491,8 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // GlobalObject interface implementation @Override - public boolean isOfContext(final Context context) { - return this.context == context; + public boolean isOfContext(final Context ctxt) { + return this.context == ctxt; } @Override diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java index 194c6d8f480..d3e2effed3f 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java @@ -30,6 +30,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; + import jdk.nashorn.api.scripting.NashornException; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; @@ -135,11 +136,12 @@ public final class NativeError extends ScriptObject { * @param errorObj the error object * @return undefined */ + @SuppressWarnings("unused") @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object captureStackTrace(final Object self, final Object errorObj) { Global.checkObject(errorObj); final ScriptObject sobj = (ScriptObject)errorObj; - final ECMAException exp = new ECMAException(sobj, null); + new ECMAException(sobj, null); //constructor has side effects sobj.delete("stack", false); final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK); final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 056d6d51437..c9deee3501d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -249,7 +249,8 @@ public final class Context { private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; - /*package-private*/ ClassLoader getSharedLoader() { + /*package-private*/ @SuppressWarnings("static-method") + ClassLoader getSharedLoader() { return sharedLoader; } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java b/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java index fa0dbede2db..e832c861450 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java @@ -65,7 +65,17 @@ public final class DebugLogger { } else { this.logger = Logging.getLogger(loggerName); } - this.isEnabled = logger.getLevel() != Level.OFF; + assert logger != null; + this.isEnabled = getLevel() != Level.OFF; + } + + /** + * Do not currently support chaining this with parent logger. Logger level null + * means disabled + * @return level + */ + private Level getLevel() { + return logger.getLevel() == null ? Level.OFF : logger.getLevel(); } /** @@ -126,7 +136,7 @@ public final class DebugLogger { * @return true if level is above the given one */ public boolean levelAbove(final Level level) { - return logger.getLevel().intValue() > level.intValue(); + return getLevel().intValue() > level.intValue(); } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java index 7e01fd6e2ea..3779f3bda9c 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java @@ -38,9 +38,10 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; public interface GlobalObject { /** * Is this global of the given Context? + * @param ctxt the context * @return true if this global belongs to the given Context */ - public boolean isOfContext(Context context); + public boolean isOfContext(final Context ctxt); /** * Does this global belong to a strict Context? diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java index 41d34600de4..44302462d17 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java @@ -119,10 +119,11 @@ public abstract class ListAdapter extends AbstractList implements Random }); } + /** wrapped object */ protected final Object obj; // allow subclasses only in this package - ListAdapter(Object obj) { + ListAdapter(final Object obj) { this.obj = obj; } @@ -143,22 +144,32 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - public final Object get(int index) { + public final Object get(final int index) { checkRange(index); return getAt(index); } + /** + * Get object at an index + * @param index index in list + * @return object + */ protected abstract Object getAt(final int index); @Override - public Object set(int index, Object element) { + public Object set(final int index, final Object element) { checkRange(index); final Object prevValue = getAt(index); setAt(index, element); return prevValue; } - protected abstract void setAt(int index, Object element); + /** + * Set object at an index + * @param index index in list + * @param element element + */ + protected abstract void setAt(final int index, final Object element); private void checkRange(int index) { if(index < 0 || index >= size()) { @@ -167,18 +178,18 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - public final void push(Object e) { + public final void push(final Object e) { addFirst(e); } @Override - public final boolean add(Object e) { + public final boolean add(final Object e) { addLast(e); return true; } @Override - public final void addFirst(Object e) { + public final void addFirst(final Object e) { try { final InvokeByName unshiftInvoker = getUNSHIFT(); final Object fn = unshiftInvoker.getGetter().invokeExact(obj); @@ -192,7 +203,7 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - public final void addLast(Object e) { + public final void addLast(final Object e) { try { final InvokeByName pushInvoker = getPUSH(); final Object fn = pushInvoker.getGetter().invokeExact(obj); @@ -206,7 +217,7 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - public final void add(int index, Object e) { + public final void add(final int index, final Object e) { try { if(index < 0) { throw invalidIndex(index); @@ -225,35 +236,35 @@ public abstract class ListAdapter extends AbstractList implements Random throw invalidIndex(index); } } - } catch(RuntimeException | Error ex) { + } catch(final RuntimeException | Error ex) { throw ex; - } catch(Throwable t) { + } catch(final Throwable t) { throw new RuntimeException(t); } } - private static void checkFunction(Object fn, InvokeByName invoke) { + private static void checkFunction(final Object fn, final InvokeByName invoke) { if(!(Bootstrap.isCallable(fn))) { throw new UnsupportedOperationException("The script object doesn't have a function named " + invoke.getName()); } } - private static IndexOutOfBoundsException invalidIndex(int index) { + private static IndexOutOfBoundsException invalidIndex(final int index) { return new IndexOutOfBoundsException(String.valueOf(index)); } @Override - public final boolean offer(Object e) { + public final boolean offer(final Object e) { return offerLast(e); } @Override - public final boolean offerFirst(Object e) { + public final boolean offerFirst(final Object e) { addFirst(e); return true; } @Override - public final boolean offerLast(Object e) { + public final boolean offerLast(final Object e) { addLast(e); return true; } @@ -287,7 +298,7 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - public final Object remove(int index) { + public final Object remove(final int index) { if(index < 0) { throw invalidIndex(index); } else if (index == 0) { @@ -333,11 +344,11 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - protected final void removeRange(int fromIndex, int toIndex) { + protected final void removeRange(final int fromIndex, final int toIndex) { invokeSpliceRemove(fromIndex, toIndex - fromIndex); } - private void invokeSpliceRemove(int fromIndex, int count) { + private void invokeSpliceRemove(final int fromIndex, final int count) { try { final InvokeByName spliceRemoveInvoker = getSPLICE_REMOVE(); final Object fn = spliceRemoveInvoker.getGetter().invokeExact(obj); @@ -419,16 +430,16 @@ public abstract class ListAdapter extends AbstractList implements Random } @Override - public final boolean removeFirstOccurrence(Object o) { + public final boolean removeFirstOccurrence(final Object o) { return removeOccurrence(o, iterator()); } @Override - public final boolean removeLastOccurrence(Object o) { + public final boolean removeLastOccurrence(final Object o) { return removeOccurrence(o, descendingIterator()); } - private static boolean removeOccurrence(Object o, Iterator it) { + private static boolean removeOccurrence(final Object o, final Iterator it) { while(it.hasNext()) { final Object e = it.next(); if(o == null ? e == null : o.equals(e)) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java index 736932ea318..42c8fb4aabe 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java @@ -64,6 +64,7 @@ final class ScriptLoader extends NashornLoader { return context.getSharedLoader().loadClass(name); } } catch (final ClassNotFoundException ignored) { + //ignored } // throw the original exception from here diff --git a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java index 7dc8307cd91..6e03dc60857 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java @@ -316,6 +316,10 @@ public final class WithObject extends ScriptObject implements Scope { return expression; } + /** + * Get the parent scope for this {@code WithObject} + * @return the parent scope + */ public ScriptObject getParentScope() { return getProto(); } From a7125b5d2ea422f94e458a70ed16dd4d316e7e33 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Thu, 10 Oct 2013 10:51:15 -0700 Subject: [PATCH 043/152] 8025633: Fix javadoc to generate valid anchor names Reviewed-by: jjg --- .../html/AbstractExecutableMemberWriter.java | 2 +- .../formats/html/AbstractIndexWriter.java | 27 +- .../html/AnnotationTypeFieldWriterImpl.java | 10 +- ...nnotationTypeOptionalMemberWriterImpl.java | 5 +- ...nnotationTypeRequiredMemberWriterImpl.java | 10 +- .../html/ConstantsSummaryWriterImpl.java | 5 +- .../formats/html/ConstructorWriterImpl.java | 11 +- .../formats/html/DeprecatedListWriter.java | 4 +- .../formats/html/EnumConstantWriterImpl.java | 22 +- .../doclets/formats/html/FieldWriterImpl.java | 25 +- .../formats/html/HtmlDocletWriter.java | 47 ++- .../formats/html/HtmlSerialFieldWriter.java | 6 - .../formats/html/HtmlSerialMethodWriter.java | 6 +- .../formats/html/MethodWriterImpl.java | 29 +- .../formats/html/NestedClassWriterImpl.java | 18 +- .../formats/html/PackageIndexWriter.java | 8 +- .../formats/html/PackageWriterImpl.java | 6 +- .../html/ProfilePackageWriterImpl.java | 6 +- .../formats/html/PropertyWriterImpl.java | 24 +- .../doclets/formats/html/SectionName.java | 80 +++++ .../formats/html/SingleIndexWriter.java | 3 +- .../formats/html/markup/HtmlDocWriter.java | 123 +++++++- .../toolkit/util/DocletConstants.java | 5 - .../javadoc/AccessSkipNav/AccessSkipNav.java | 10 +- .../testAnchorNames/TestAnchorNames.java | 290 ++++++++++++++++++ .../testAnchorNames/pkg1/DeprMemClass.java | 45 +++ .../testAnchorNames/pkg1/RegClass.java | 186 +++++++++++ .../TestAnnotationOptional.java | 7 +- .../TestAnnotationTypes.java | 10 +- .../TestClassCrossReferences.java | 4 +- .../TestExternalOverridenMethod.java | 9 +- .../com/sun/javadoc/testHref/TestHref.java | 14 +- .../TestHtmlDefinitionListTag.java | 32 +- .../javadoc/testInterface/TestInterface.java | 6 +- .../sun/javadoc/testJavaFX/TestJavaFX.java | 8 +- .../testLinkTaglet/TestLinkTaglet.java | 8 +- .../TestMemberInheritence.java | 12 +- .../testMemberSummary/TestMemberSummary.java | 8 +- .../testNavigation/TestNavigation.java | 4 +- .../TestNestedGenerics.java | 6 +- .../TestNewLanguageFeatures.java | 76 ++--- .../TestOverridenMethodDocCopy.java | 4 +- ...verridenPrivateMethodsWithPackageFlag.java | 8 +- .../TestPrivateClasses.java | 20 +- .../TestSerializedFormDeprecationInfo.java | 14 +- .../sun/javadoc/testTaglets/TestTaglets.java | 6 +- .../TestTypeAnnotations.java | 16 +- .../testTypeParams/TestTypeParameters.java | 4 +- .../javadoc/testWarnings/TestWarnings.java | 6 +- 49 files changed, 1046 insertions(+), 249 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/SectionName.java create mode 100644 langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java create mode 100644 langtools/test/com/sun/javadoc/testAnchorNames/pkg1/DeprMemClass.java create mode 100644 langtools/test/com/sun/javadoc/testAnchorNames/pkg1/RegClass.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java index 9c20777e137..23f4f00cd7f 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java @@ -305,6 +305,6 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite buf.append(t.dimension()); } buf.append(")"); - return foundTypeVariable ? buf.toString() : null; + return foundTypeVariable ? writer.getName(buf.toString()) : null; } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java index 87a5bce3367..4b7ca05e384 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java @@ -89,10 +89,11 @@ public class AbstractIndexWriter extends HtmlDocletWriter { * @param memberlist List of members for the unicode character * @param contentTree the content tree to which the information will be added */ - protected void addContents(Character unicode, List memberlist, + protected void addContents(Character uc, List memberlist, Content contentTree) { - contentTree.addContent(getMarkerAnchor("_" + unicode + "_")); - Content headContent = new StringContent(unicode.toString()); + String unicode = uc.toString(); + contentTree.addContent(getMarkerAnchorForIndex(unicode)); + Content headContent = new StringContent(unicode); Content heading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, false, HtmlStyle.title, headContent); contentTree.addContent(heading); @@ -253,4 +254,24 @@ public class AbstractIndexWriter extends HtmlDocletWriter { addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, containing, false, contentTree); } + + /** + * Get the marker anchor which will be added to the index documentation tree. + * + * @param anchorNameForIndex the anchor name attribute for index page + * @return a content tree for the marker anchor + */ + public Content getMarkerAnchorForIndex(String anchorNameForIndex) { + return getMarkerAnchor(getNameForIndex(anchorNameForIndex), null); + } + + /** + * Generate a valid HTML name for member index page. + * + * @param unicode the string that needs to be converted to valid HTML name. + * @return a valid HTML name string. + */ + public String getNameForIndex(String unicode) { + return "I:" + getName(unicode); + } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java index f4c7c68f565..bb936d37324 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java @@ -88,7 +88,7 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter Content memberDetailsTree) { if (!writer.printedAnnotationFieldHeading) { memberDetailsTree.addContent(writer.getMarkerAnchor( - "annotation_type_field_detail")); + SectionName.ANNOTATION_TYPE_FIELD_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.fieldDetailsLabel); memberDetailsTree.addContent(heading); @@ -217,7 +217,7 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { memberTree.addContent(writer.getMarkerAnchor( - "annotation_type_field_summary")); + SectionName.ANNOTATION_TYPE_FIELD_SUMMARY)); } /** @@ -272,7 +272,8 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink("annotation_type_field_summary", + return writer.getHyperLink( + SectionName.ANNOTATION_TYPE_FIELD_SUMMARY, writer.getResource("doclet.navField")); } else { return writer.getResource("doclet.navField"); @@ -284,7 +285,8 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("annotation_type_field_detail", + liNav.addContent(writer.getHyperLink( + SectionName.ANNOTATION_TYPE_FIELD_DETAIL, writer.getResource("doclet.navField"))); } else { liNav.addContent(writer.getResource("doclet.navField")); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java index ff8fc100f0a..9a586a017f3 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java @@ -133,7 +133,7 @@ public class AnnotationTypeOptionalMemberWriterImpl extends */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { memberTree.addContent(writer.getMarkerAnchor( - "annotation_type_optional_element_summary")); + SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY)); } /** @@ -141,7 +141,8 @@ public class AnnotationTypeOptionalMemberWriterImpl extends */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink("annotation_type_optional_element_summary", + return writer.getHyperLink( + SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY, writer.getResource("doclet.navAnnotationTypeOptionalMember")); } else { return writer.getResource("doclet.navAnnotationTypeOptionalMember"); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java index 1833d262db3..bdbe8d547c2 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java @@ -89,7 +89,7 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter Content memberDetailsTree) { if (!writer.printedAnnotationHeading) { memberDetailsTree.addContent(writer.getMarkerAnchor( - "annotation_type_element_detail")); + SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.annotationTypeDetailsLabel); memberDetailsTree.addContent(heading); @@ -219,7 +219,7 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { memberTree.addContent(writer.getMarkerAnchor( - "annotation_type_required_element_summary")); + SectionName.ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY)); } /** @@ -274,7 +274,8 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink("annotation_type_required_element_summary", + return writer.getHyperLink( + SectionName.ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY, writer.getResource("doclet.navAnnotationTypeRequiredMember")); } else { return writer.getResource("doclet.navAnnotationTypeRequiredMember"); @@ -286,7 +287,8 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("annotation_type_element_detail", + liNav.addContent(writer.getHyperLink( + SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL, writer.getResource("doclet.navAnnotationTypeMember"))); } else { liNav.addContent(writer.getResource("doclet.navAnnotationTypeMember")); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java index cb9ab3e3078..21f0c215038 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java @@ -107,7 +107,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter //add link to summary Content link; if (packageName.length() == 0) { - link = getHyperLink(DocLink.fragment(DocletConstants.UNNAMED_PACKAGE_ANCHOR), + link = getHyperLink(getDocLink( + SectionName.UNNAMED_PACKAGE_ANCHOR), defaultPackageLabel, "", ""); } else { Content packageNameContent = getPackageLabel(parsedPackageName); @@ -153,7 +154,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter Content pkgNameContent; if (parsedPackageName.length() == 0) { summariesTree.addContent(getMarkerAnchor( - DocletConstants.UNNAMED_PACKAGE_ANCHOR)); + SectionName.UNNAMED_PACKAGE_ANCHOR)); pkgNameContent = defaultPackageLabel; } else { summariesTree.addContent(getMarkerAnchor( diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java index 496737078dd..856a4827e3c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java @@ -97,7 +97,8 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter Content memberDetailsTree) { memberDetailsTree.addContent(HtmlConstants.START_OF_CONSTRUCTOR_DETAILS); Content constructorDetailsTree = writer.getMemberTreeHeader(); - constructorDetailsTree.addContent(writer.getMarkerAnchor("constructor_detail")); + constructorDetailsTree.addContent(writer.getMarkerAnchor( + SectionName.CONSTRUCTOR_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.constructorDetailsLabel); constructorDetailsTree.addContent(heading); @@ -256,7 +257,8 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter * {@inheritDoc} */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { - memberTree.addContent(writer.getMarkerAnchor("constructor_summary")); + memberTree.addContent(writer.getMarkerAnchor( + SectionName.CONSTRUCTOR_SUMMARY)); } /** @@ -280,7 +282,7 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink("constructor_summary", + return writer.getHyperLink(SectionName.CONSTRUCTOR_SUMMARY, writer.getResource("doclet.navConstructor")); } else { return writer.getResource("doclet.navConstructor"); @@ -292,7 +294,8 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("constructor_detail", + liNav.addContent(writer.getHyperLink( + SectionName.CONSTRUCTOR_DETAIL, writer.getResource("doclet.navConstructor"))); } else { liNav.addContent(writer.getResource("doclet.navConstructor")); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java index 00135fc6cec..63c81438956 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java @@ -48,8 +48,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter { private static final String[] ANCHORS = new String[] { "package", "interface", "class", "enum", "exception", "error", - "annotation_type", "field", "method", "constructor", "enum_constant", - "annotation_type_member" + "annotation.type", "field", "method", "constructor", "enum.constant", + "annotation.type.member" }; private static final String[] HEADING_KEYS = new String[] { diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java index 382f16f1f00..b971d07668d 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java @@ -73,7 +73,8 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter Content memberDetailsTree) { memberDetailsTree.addContent(HtmlConstants.START_OF_ENUM_CONSTANT_DETAILS); Content enumConstantsDetailsTree = writer.getMemberTreeHeader(); - enumConstantsDetailsTree.addContent(writer.getMarkerAnchor("enum_constant_detail")); + enumConstantsDetailsTree.addContent(writer.getMarkerAnchor( + SectionName.ENUM_CONSTANT_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.enumConstantsDetailsLabel); enumConstantsDetailsTree.addContent(heading); @@ -202,7 +203,8 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter * {@inheritDoc} */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { - memberTree.addContent(writer.getMarkerAnchor("enum_constant_summary")); + memberTree.addContent(writer.getMarkerAnchor( + SectionName.ENUM_CONSTANT_SUMMARY)); } /** @@ -263,11 +265,14 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink((cd == null)? - "enum_constant_summary": - "enum_constants_inherited_from_class_" + - configuration.getClassName(cd), - writer.getResource("doclet.navEnum")); + if (cd == null) { + return writer.getHyperLink(SectionName.ENUM_CONSTANT_SUMMARY, + writer.getResource("doclet.navEnum")); + } else { + return writer.getHyperLink( + SectionName.ENUM_CONSTANTS_INHERITANCE, + configuration.getClassName(cd), writer.getResource("doclet.navEnum")); + } } else { return writer.getResource("doclet.navEnum"); } @@ -278,7 +283,8 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("enum_constant_detail", + liNav.addContent(writer.getHyperLink( + SectionName.ENUM_CONSTANT_DETAIL, writer.getResource("doclet.navEnum"))); } else { liNav.addContent(writer.getResource("doclet.navEnum")); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java index f599ac2ff6b..104967129f7 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java @@ -74,7 +74,8 @@ public class FieldWriterImpl extends AbstractMemberWriter Content memberDetailsTree) { memberDetailsTree.addContent(HtmlConstants.START_OF_FIELD_DETAILS); Content fieldDetailsTree = writer.getMemberTreeHeader(); - fieldDetailsTree.addContent(writer.getMarkerAnchor("field_detail")); + fieldDetailsTree.addContent(writer.getMarkerAnchor( + SectionName.FIELD_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.fieldDetailsLabel); fieldDetailsTree.addContent(heading); @@ -224,7 +225,8 @@ public class FieldWriterImpl extends AbstractMemberWriter * {@inheritDoc} */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { - memberTree.addContent(writer.getMarkerAnchor("field_summary")); + memberTree.addContent(writer.getMarkerAnchor( + SectionName.FIELD_SUMMARY)); } /** @@ -232,7 +234,7 @@ public class FieldWriterImpl extends AbstractMemberWriter */ public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) { inheritedTree.addContent(writer.getMarkerAnchor( - "fields_inherited_from_class_" + configuration.getClassName(cd))); + SectionName.FIELDS_INHERITANCE, configuration.getClassName(cd))); } /** @@ -293,11 +295,15 @@ public class FieldWriterImpl extends AbstractMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink((cd == null)? - "field_summary": - "fields_inherited_from_class_" + - configuration.getClassName(cd), - writer.getResource("doclet.navField")); + if (cd == null) { + return writer.getHyperLink( + SectionName.FIELD_SUMMARY, + writer.getResource("doclet.navField")); + } else { + return writer.getHyperLink( + SectionName.FIELDS_INHERITANCE, + configuration.getClassName(cd), writer.getResource("doclet.navField")); + } } else { return writer.getResource("doclet.navField"); } @@ -308,7 +314,8 @@ public class FieldWriterImpl extends AbstractMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("field_detail", + liNav.addContent(writer.getHyperLink( + SectionName.FIELD_DETAIL, writer.getResource("doclet.navField"))); } else { liNav.addContent(writer.getResource("doclet.navField")); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index 3bdcf6a3b10..19a578c85cb 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -509,28 +509,28 @@ public class HtmlDocletWriter extends HtmlDocWriter { body.addContent(HtmlConstants.START_OF_TOP_NAVBAR); navDiv.addStyle(HtmlStyle.topNav); allClassesId += "navbar_top"; - Content a = getMarkerAnchor("navbar_top"); + Content a = getMarkerAnchor(SectionName.NAVBAR_TOP); //WCAG - Hyperlinks should contain text or an image with alt text - for AT tools navDiv.addContent(a); Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink( - DocLink.fragment("skip-navbar_top"), skipNavLinks, + getDocLink(SectionName.SKIP_NAVBAR_TOP), skipNavLinks, skipNavLinks.toString(), "")); navDiv.addContent(skipLinkContent); } else { body.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR); navDiv.addStyle(HtmlStyle.bottomNav); allClassesId += "navbar_bottom"; - Content a = getMarkerAnchor("navbar_bottom"); + Content a = getMarkerAnchor(SectionName.NAVBAR_BOTTOM); navDiv.addContent(a); Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink( - DocLink.fragment("skip-navbar_bottom"), skipNavLinks, + getDocLink(SectionName.SKIP_NAVBAR_BOTTOM), skipNavLinks, skipNavLinks.toString(), "")); navDiv.addContent(skipLinkContent); } if (header) { - navDiv.addContent(getMarkerAnchor("navbar_top_firstrow")); + navDiv.addContent(getMarkerAnchor(SectionName.NAVBAR_TOP_FIRSTROW)); } else { - navDiv.addContent(getMarkerAnchor("navbar_bottom_firstrow")); + navDiv.addContent(getMarkerAnchor(SectionName.NAVBAR_BOTTOM_FIRSTROW)); } HtmlTree navList = new HtmlTree(HtmlTag.UL); navList.addStyle(HtmlStyle.navList); @@ -577,11 +577,11 @@ public class HtmlDocletWriter extends HtmlDocWriter { subDiv.addContent(getAllClassesLinkScript(allClassesId.toString())); addSummaryDetailLinks(subDiv); if (header) { - subDiv.addContent(getMarkerAnchor("skip-navbar_top")); + subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_TOP)); body.addContent(subDiv); body.addContent(HtmlConstants.END_OF_TOP_NAVBAR); } else { - subDiv.addContent(getMarkerAnchor("skip-navbar_bottom")); + subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_BOTTOM)); body.addContent(subDiv); body.addContent(HtmlConstants.END_OF_BOTTOM_NAVBAR); } @@ -886,7 +886,28 @@ public class HtmlDocletWriter extends HtmlDocWriter { * @return a content tree for the marker anchor */ public Content getMarkerAnchor(String anchorName) { - return getMarkerAnchor(anchorName, null); + return getMarkerAnchor(getName(anchorName), null); + } + + /** + * Get the marker anchor which will be added to the documentation tree. + * + * @param sectionName the section name anchor attribute for page + * @return a content tree for the marker anchor + */ + public Content getMarkerAnchor(SectionName sectionName) { + return getMarkerAnchor(sectionName.getName(), null); + } + + /** + * Get the marker anchor which will be added to the documentation tree. + * + * @param sectionName the section name anchor attribute for page + * @param anchorName the anchor name combined with section name attribute for the page + * @return a content tree for the marker anchor + */ + public Content getMarkerAnchor(SectionName sectionName, String anchorName) { + return getMarkerAnchor(sectionName.getName() + getName(anchorName), null); } /** @@ -1291,10 +1312,10 @@ public class HtmlDocletWriter extends HtmlDocWriter { } else if (doc instanceof ExecutableMemberDoc) { ExecutableMemberDoc emd = (ExecutableMemberDoc)doc; return getLink(new LinkInfoImpl(configuration, context, classDoc) - .label(label).where(getAnchor(emd, isProperty)).strong(strong)); + .label(label).where(getName(getAnchor(emd, isProperty))).strong(strong)); } else if (doc instanceof MemberDoc) { return getLink(new LinkInfoImpl(configuration, context, classDoc) - .label(label).where(doc.name()).strong(strong)); + .label(label).where(getName(doc.name())).strong(strong)); } else { return label; } @@ -1319,10 +1340,10 @@ public class HtmlDocletWriter extends HtmlDocWriter { } else if (doc instanceof ExecutableMemberDoc) { ExecutableMemberDoc emd = (ExecutableMemberDoc) doc; return getLink(new LinkInfoImpl(configuration, context, classDoc) - .label(label).where(getAnchor(emd))); + .label(label).where(getName(getAnchor(emd)))); } else if (doc instanceof MemberDoc) { return getLink(new LinkInfoImpl(configuration, context, classDoc) - .label(label).where(doc.name())); + .label(label).where(getName(doc.name()))); } else { return label; } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java index 8918889a4c1..8597adaeba2 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java @@ -49,8 +49,6 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl implements SerializedFormWriter.SerialFieldWriter { ProgramElementDoc[] members = null; - private boolean printedOverallAnchor = false; - public HtmlSerialFieldWriter(SubWriterHolderWriter writer, ClassDoc classdoc) { super(writer, classdoc); @@ -98,10 +96,6 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl HtmlTree li = new HtmlTree(HtmlTag.LI); li.addStyle(HtmlStyle.blockList); if (serializableFieldsTree.isValid()) { - if (!printedOverallAnchor) { - li.addContent(writer.getMarkerAnchor("serializedForm")); - printedOverallAnchor = true; - } Content headingContent = new StringContent(heading); Content serialHeading = HtmlTree.HEADING(HtmlConstants.SERIALIZED_MEMBER_HEADING, headingContent); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java index 4e5da21fc7f..082745db179 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java @@ -85,12 +85,10 @@ public class HtmlSerialMethodWriter extends MethodWriterImpl implements * @return a content tree for the serializable methods content */ public Content getSerializableMethods(String heading, Content serializableMethodContent) { - Content li = HtmlTree.LI(HtmlStyle.blockList, writer.getMarkerAnchor( - "serialized_methods")); Content headingContent = new StringContent(heading); Content serialHeading = HtmlTree.HEADING(HtmlConstants.SERIALIZED_MEMBER_HEADING, headingContent); - li.addContent(serialHeading); + Content li = HtmlTree.LI(HtmlStyle.blockList, serialHeading); li.addContent(serializableMethodContent); return li; } @@ -113,8 +111,6 @@ public class HtmlSerialMethodWriter extends MethodWriterImpl implements * @param methodsContentTree the content tree to which the member header will be added */ public void addMemberHeader(MethodDoc member, Content methodsContentTree) { - methodsContentTree.addContent(writer.getMarkerAnchor( - writer.getAnchor(member))); methodsContentTree.addContent(getHead(member)); methodsContentTree.addContent(getSignature(member)); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java index bb67b99c200..8b3712d3594 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java @@ -85,7 +85,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter Content memberDetailsTree) { memberDetailsTree.addContent(HtmlConstants.START_OF_METHOD_DETAILS); Content methodDetailsTree = writer.getMemberTreeHeader(); - methodDetailsTree.addContent(writer.getMarkerAnchor("method_detail")); + methodDetailsTree.addContent(writer.getMarkerAnchor( + SectionName.METHOD_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.methodDetailsLabel); methodDetailsTree.addContent(heading); @@ -244,7 +245,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter * {@inheritDoc} */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { - memberTree.addContent(writer.getMarkerAnchor("method_summary")); + memberTree.addContent(writer.getMarkerAnchor( + SectionName.METHOD_SUMMARY)); } /** @@ -252,8 +254,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter */ public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) { inheritedTree.addContent(writer.getMarkerAnchor( - "methods_inherited_from_class_" + - configuration.getClassName(cd))); + SectionName.METHODS_INHERITANCE, configuration.getClassName(cd))); } /** @@ -318,7 +319,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter Content methlink = writer.getLink( new LinkInfoImpl(writer.configuration, LinkInfoImpl.Kind.MEMBER, overriddenType.asClassDoc()) - .where(writer.getAnchor(method)).label(name)); + .where(writer.getName(writer.getAnchor(method))).label(name)); Content codeMethLink = HtmlTree.CODE(methlink); Content dd = HtmlTree.DD(codeMethLink); dd.addContent(writer.getSpace()); @@ -400,11 +401,15 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink((cd == null)? - "method_summary": - "methods_inherited_from_class_" + - configuration.getClassName(cd), - writer.getResource("doclet.navMethod")); + if (cd == null) { + return writer.getHyperLink( + SectionName.METHOD_SUMMARY, + writer.getResource("doclet.navMethod")); + } else { + return writer.getHyperLink( + SectionName.METHODS_INHERITANCE, + configuration.getClassName(cd), writer.getResource("doclet.navMethod")); + } } else { return writer.getResource("doclet.navMethod"); } @@ -415,8 +420,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("method_detail", - writer.getResource("doclet.navMethod"))); + liNav.addContent(writer.getHyperLink( + SectionName.METHOD_DETAIL, writer.getResource("doclet.navMethod"))); } else { liNav.addContent(writer.getResource("doclet.navMethod")); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java index d44dd25feb0..d0537af4a41 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java @@ -132,7 +132,8 @@ public class NestedClassWriterImpl extends AbstractMemberWriter * {@inheritDoc} */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { - memberTree.addContent(writer.getMarkerAnchor("nested_class_summary")); + memberTree.addContent(writer.getMarkerAnchor( + SectionName.NESTED_CLASS_SUMMARY)); } /** @@ -140,7 +141,8 @@ public class NestedClassWriterImpl extends AbstractMemberWriter */ public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) { inheritedTree.addContent(writer.getMarkerAnchor( - "nested_classes_inherited_from_class_" + cd.qualifiedName())); + SectionName.NESTED_CLASSES_INHERITANCE, + cd.qualifiedName())); } /** @@ -202,9 +204,15 @@ public class NestedClassWriterImpl extends AbstractMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink((cd == null) ? "nested_class_summary": - "nested_classes_inherited_from_class_" + cd.qualifiedName(), - writer.getResource("doclet.navNested")); + if (cd == null) { + return writer.getHyperLink( + SectionName.NESTED_CLASS_SUMMARY, + writer.getResource("doclet.navNested")); + } else { + return writer.getHyperLink( + SectionName.NESTED_CLASSES_INHERITANCE, + cd.qualifiedName(), writer.getResource("doclet.navNested")); + } } else { return writer.getResource("doclet.navNested"); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java index caf0e0976a6..ffb93b73f21 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java @@ -203,8 +203,9 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter { Content see = seeLabel; see.addContent(" "); Content descPara = HtmlTree.P(see); - Content descLink = getHyperLink(DocLink.fragment("overview_description"), - descriptionLabel, "", ""); + Content descLink = getHyperLink(getDocLink( + SectionName.OVERVIEW_DESCRIPTION), + descriptionLabel, "", ""); descPara.addContent(descLink); div.addContent(descPara); body.addContent(div); @@ -220,7 +221,8 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter { */ protected void addOverviewComment(Content htmltree) { if (root.inlineTags().length > 0) { - htmltree.addContent(getMarkerAnchor("overview_description")); + htmltree.addContent( + getMarkerAnchor(SectionName.OVERVIEW_DESCRIPTION)); addInlineComment(root, htmltree); } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java index f0325b5b953..c19bf2d6549 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java @@ -112,7 +112,8 @@ public class PackageWriterImpl extends HtmlDocletWriter addSummaryComment(packageDoc, docSummaryDiv); div.addContent(docSummaryDiv); Content space = getSpace(); - Content descLink = getHyperLink(DocLink.fragment("package_description"), + Content descLink = getHyperLink(getDocLink( + SectionName.PACKAGE_DESCRIPTION), descriptionLabel, "", ""); Content descPara = new HtmlTree(HtmlTag.P, seeLabel, space, descLink); div.addContent(descPara); @@ -211,7 +212,8 @@ public class PackageWriterImpl extends HtmlDocletWriter */ public void addPackageDescription(Content packageContentTree) { if (packageDoc.inlineTags().length > 0) { - packageContentTree.addContent(getMarkerAnchor("package_description")); + packageContentTree.addContent( + getMarkerAnchor(SectionName.PACKAGE_DESCRIPTION)); Content h2Content = new StringContent( configuration.getText("doclet.Package_Description", packageDoc.name())); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java index 1de03f40898..7f2c6e61111 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java @@ -129,7 +129,8 @@ public class ProfilePackageWriterImpl extends HtmlDocletWriter addSummaryComment(packageDoc, docSummaryDiv); div.addContent(docSummaryDiv); Content space = getSpace(); - Content descLink = getHyperLink(DocLink.fragment("package_description"), + Content descLink = getHyperLink(getDocLink( + SectionName.PACKAGE_DESCRIPTION), descriptionLabel, "", ""); Content descPara = new HtmlTree(HtmlTag.P, seeLabel, space, descLink); div.addContent(descPara); @@ -192,7 +193,8 @@ public class ProfilePackageWriterImpl extends HtmlDocletWriter */ public void addPackageDescription(Content packageContentTree) { if (packageDoc.inlineTags().length > 0) { - packageContentTree.addContent(getMarkerAnchor("package_description")); + packageContentTree.addContent( + getMarkerAnchor(SectionName.PACKAGE_DESCRIPTION)); Content h2Content = new StringContent( configuration.getText("doclet.Package_Description", packageDoc.name())); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java index 838732b5212..9bf4bf0ca26 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java @@ -70,7 +70,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter Content memberDetailsTree) { memberDetailsTree.addContent(HtmlConstants.START_OF_PROPERTY_DETAILS); Content propertyDetailsTree = writer.getMemberTreeHeader(); - propertyDetailsTree.addContent(writer.getMarkerAnchor("property_detail")); + propertyDetailsTree.addContent(writer.getMarkerAnchor( + SectionName.PROPERTY_DETAIL)); Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, writer.propertyDetailsLabel); propertyDetailsTree.addContent(heading); @@ -220,7 +221,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter * {@inheritDoc} */ public void addSummaryAnchor(ClassDoc cd, Content memberTree) { - memberTree.addContent(writer.getMarkerAnchor("property_summary")); + memberTree.addContent(writer.getMarkerAnchor( + SectionName.PROPERTY_SUMMARY)); } /** @@ -228,7 +230,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter */ public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) { inheritedTree.addContent(writer.getMarkerAnchor( - "properties_inherited_from_class_" + configuration.getClassName(cd))); + SectionName.PROPERTIES_INHERITANCE, + configuration.getClassName(cd))); } /** @@ -297,11 +300,15 @@ public class PropertyWriterImpl extends AbstractMemberWriter */ protected Content getNavSummaryLink(ClassDoc cd, boolean link) { if (link) { - return writer.getHyperLink((cd == null)? - "property_summary": - "properties_inherited_from_class_" + - configuration.getClassName(cd), + if (cd == null) { + return writer.getHyperLink( + SectionName.PROPERTY_SUMMARY, writer.getResource("doclet.navProperty")); + } else { + return writer.getHyperLink( + SectionName.PROPERTIES_INHERITANCE, + configuration.getClassName(cd), writer.getResource("doclet.navProperty")); + } } else { return writer.getResource("doclet.navProperty"); } @@ -312,7 +319,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter */ protected void addNavDetailLink(boolean link, Content liNav) { if (link) { - liNav.addContent(writer.getHyperLink("property_detail", + liNav.addContent(writer.getHyperLink( + SectionName.PROPERTY_DETAIL, writer.getResource("doclet.navProperty"))); } else { liNav.addContent(writer.getResource("doclet.navProperty")); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SectionName.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SectionName.java new file mode 100644 index 00000000000..b27949fe988 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SectionName.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.formats.html; + +/** + * Enum representing various section names of generated API documentation. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * @author Bhavesh Patel + */ +public enum SectionName { + + ANNOTATION_TYPE_ELEMENT_DETAIL("annotation.type.element.detail"), + ANNOTATION_TYPE_FIELD_DETAIL("annotation.type.field.detail"), + ANNOTATION_TYPE_FIELD_SUMMARY("annotation.type.field.summary"), + ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY("annotation.type.optional.element.summary"), + ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY("annotation.type.required.element.summary"), + CONSTRUCTOR_DETAIL("constructor.detail"), + CONSTRUCTOR_SUMMARY("constructor.summary"), + ENUM_CONSTANT_DETAIL("enum.constant.detail"), + ENUM_CONSTANTS_INHERITANCE("enum.constants.inherited.from.class."), + ENUM_CONSTANT_SUMMARY("enum.constant.summary"), + FIELD_DETAIL("field.detail"), + FIELDS_INHERITANCE("fields.inherited.from.class."), + FIELD_SUMMARY("field.summary"), + METHOD_DETAIL("method.detail"), + METHODS_INHERITANCE("methods.inherited.from.class."), + METHOD_SUMMARY("method.summary"), + NAVBAR_BOTTOM("navbar.bottom"), + NAVBAR_BOTTOM_FIRSTROW("navbar.bottom.firstrow"), + NAVBAR_TOP("navbar.top"), + NAVBAR_TOP_FIRSTROW("navbar.top.firstrow"), + NESTED_CLASSES_INHERITANCE("nested.classes.inherited.from.class."), + NESTED_CLASS_SUMMARY("nested.class.summary"), + OVERVIEW_DESCRIPTION("overview.description"), + PACKAGE_DESCRIPTION("package.description"), + PROPERTY_DETAIL("property.detail"), + PROPERTIES_INHERITANCE("properties.inherited.from.class."), + PROPERTY_SUMMARY("property.summary"), + SKIP_NAVBAR_BOTTOM("skip.navbar.bottom"), + SKIP_NAVBAR_TOP("skip.navbar.top"), + UNNAMED_PACKAGE_ANCHOR("unnamed.package"); + + private final String value; + + SectionName(String sName) { + this.value = sName; + } + + public String getName() { + return this.value; + } +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java index 43718e4699c..a561a0395d0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java @@ -115,7 +115,8 @@ public class SingleIndexWriter extends AbstractIndexWriter { for (int i = 0; i < indexbuilder.elements().length; i++) { String unicode = (indexbuilder.elements())[i].toString(); contentTree.addContent( - getHyperLink("_" + unicode + "_", new StringContent(unicode))); + getHyperLink(getNameForIndex(unicode), + new StringContent(unicode))); contentTree.addContent(getSpace()); } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java index c780e962cac..ee8cc9cb12e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java @@ -30,6 +30,7 @@ import java.util.*; import com.sun.javadoc.*; import com.sun.tools.doclets.formats.html.ConfigurationImpl; +import com.sun.tools.doclets.formats.html.SectionName; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.util.DocFile; import com.sun.tools.doclets.internal.toolkit.util.DocLink; @@ -78,7 +79,7 @@ public abstract class HtmlDocWriter extends HtmlWriter { } /** - * Get Html Hyper Link string. + * Get Html Hyper Link Content. * * @param where Position of the link in the file. Character '#' is not * needed. @@ -87,7 +88,125 @@ public abstract class HtmlDocWriter extends HtmlWriter { */ public Content getHyperLink(String where, Content label) { - return getHyperLink(DocLink.fragment(where), label, "", ""); + return getHyperLink(getDocLink(where), label, "", ""); + } + + /** + * Get Html Hyper Link Content. + * + * @param sectionName The section name to which the link will be created. + * @param label Tag for the link. + * @return a content tree for the hyper link + */ + public Content getHyperLink(SectionName sectionName, + Content label) { + return getHyperLink(getDocLink(sectionName), label, "", ""); + } + + /** + * Get Html Hyper Link Content. + * + * @param sectionName The section name combined with where to which the link + * will be created. + * @param where The fragment combined with sectionName to which the link + * will be created. + * @param label Tag for the link. + * @return a content tree for the hyper link + */ + public Content getHyperLink(SectionName sectionName, String where, + Content label) { + return getHyperLink(getDocLink(sectionName, where), label, "", ""); + } + + /** + * Get the link. + * + * @param where Position of the link in the file. + * @return a DocLink object for the hyper link + */ + public DocLink getDocLink(String where) { + return DocLink.fragment(getName(where)); + } + + /** + * Get the link. + * + * @param sectionName The section name to which the link will be created. + * @return a DocLink object for the hyper link + */ + public DocLink getDocLink(SectionName sectionName) { + return DocLink.fragment(sectionName.getName()); + } + + /** + * Get the link. + * + * @param sectionName The section name combined with where to which the link + * will be created. + * @param where The fragment combined with sectionName to which the link + * will be created. + * @return a DocLink object for the hyper link + */ + public DocLink getDocLink(SectionName sectionName, String where) { + return DocLink.fragment(sectionName.getName() + getName(where)); + } + + /** + * Convert the name to a valid HTML name. + * + * @param name the name that needs to be converted to valid HTML name. + * @return a valid HTML name string. + */ + public String getName(String name) { + StringBuilder sb = new StringBuilder(); + char ch; + /* The HTML 4 spec at http://www.w3.org/TR/html4/types.html#h-6.2 mentions + * that the name/id should begin with a letter followed by other valid characters. + * The HTML 5 spec (draft) is more permissive on names/ids where the only restriction + * is that it should be at least one character long and should not contain spaces. + * The spec draft is @ http://www.w3.org/html/wg/drafts/html/master/dom.html#the-id-attribute. + * + * For HTML 4, we need to check for non-characters at the beginning of the name and + * substitute it accordingly, "_" and "$" can appear at the beginning of a member name. + * The method substitutes "$" with "Z:Z:D" and will prefix "_" with "Z:Z". + */ + for (int i = 0; i < name.length(); i++) { + ch = name.charAt(i); + switch (ch) { + case '(': + case ')': + case '<': + case '>': + case ',': + sb.append('-'); + break; + case ' ': + case '[': + break; + case ']': + sb.append(":A"); + break; + // Any appearance of $ needs to be substituted with ":D" and not with hyphen + // since a field name "P$$ and a method P(), both valid member names, can end + // up as "P--". A member name beginning with $ needs to be substituted with + // "Z:Z:D". + case '$': + if (i == 0) + sb.append("Z:Z"); + sb.append(":D"); + break; + // A member name beginning with _ needs to be prefixed with "Z:Z" since valid anchor + // names can only begin with a letter. + case '_': + if (i == 0) + sb.append("Z:Z"); + sb.append(ch); + break; + default: + sb.append(ch); + } + } + return sb.toString(); } /** diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java index c76b2ed26c1..5742cd0bf6a 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java @@ -58,9 +58,4 @@ public class DocletConstants { * The default package file name. */ public static final String DEFAULT_PACKAGE_FILE_NAME = "default"; - - /** - * The anchor for the default package. - */ - public static final String UNNAMED_PACKAGE_ANCHOR = "unnamed_package"; } diff --git a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java index 6ad89feb8bf..0c05190333f 100644 --- a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java +++ b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4638136 7198273 + * @bug 4638136 7198273 8025633 * @summary Add ability to skip over nav bar for accessibility * @author dkramer * @run main AccessSkipNav @@ -86,20 +86,20 @@ public class AccessSkipNav { // Testing only for the presence of the and // Top navbar - { "Skip navigation links", + { "Skip navigation links", TMPDEST_DIR1 + "p1" + FS + "C1.html" }, // Top navbar - { "" + LS + + { "" + LS + "" + LS + "", TMPDEST_DIR1 + "p1" + FS + "C1.html" }, // Bottom navbar - { "Skip navigation links", + { "Skip navigation links", TMPDEST_DIR1 + "p1" + FS + "C1.html" }, // Bottom navbar - { "" + LS + + { "" + LS + "" + LS + "", TMPDEST_DIR1 + "p1" + FS + "C1.html" } }; diff --git a/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java b/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java new file mode 100644 index 00000000000..c5cb7519325 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025633 + * @summary Test for valid name attribute in HTML anchors. + * @author Bhavesh Patel + * @library ../lib/ + * @build JavadocTester TestAnchorNames + * @run main TestAnchorNames + */ + +public class TestAnchorNames extends JavadocTester { + + private static final String BUG_ID = "8025633"; + + //Input for string search tests. + private static final String[][] TEST = { + + //Test some section markers and links to these markers + + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + + //Test some members and link to these members + + //The marker for this appears in the serialized-form.html which we will + //test below + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + //Test some fields + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "DeprMemClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "DeprMemClass.html", + "" + }, + //Test constructor + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + //Test some methods + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "DeprMemClass.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "DeprMemClass.html", + "" + }, + + //Test enum + + {BUG_ID + FS + "pkg1" + FS + "RegClass.Te$t_Enum.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.Te$t_Enum.html", + "" + }, + + //Test nested class + + {BUG_ID + FS + "pkg1" + FS + "RegClass._NestedClas$.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass._NestedClas$.html", + "" + }, + + //Test class use page + + {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "DeprMemClass.html", + "" + }, + + //Test deprecated list page + + {BUG_ID + FS + "deprecated-list.html", + "" + }, + {BUG_ID + FS + "deprecated-list.html", + "" + }, + + //Test constant values page + + {BUG_ID + FS + "constant-values.html", + "" + }, + + //Test serialized form page + + //This is the marker for the link that appears in the pkg1.RegClass.html page + {BUG_ID + FS + "serialized-form.html", + "" + }, + + //Test member name index page + + {BUG_ID + FS + "index-all.html", + "" + }, + {BUG_ID + FS + "index-all.html", + "$" + }, + {BUG_ID + FS + "index-all.html", + "_" + } + }; + + private static final String[][] NEGATED_TEST = { + //The marker name conversion should only affect HTML anchors. It should not + //affect the lables. + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + " Z:Z_" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + " Z:Z:Dfield" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + " Z:Z_field_In_Class" + }, + {BUG_ID + FS + "pkg1" + FS + "RegClass.html", + " S_:D:D:D:D:DINT" + }, + }; + + private static final String[] ARGS = new String[] { + "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "pkg1" + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) throws Exception { + TestAnchorNames tester = new TestAnchorNames(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/testAnchorNames/pkg1/DeprMemClass.java b/langtools/test/com/sun/javadoc/testAnchorNames/pkg1/DeprMemClass.java new file mode 100644 index 00000000000..7d2407656e6 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnchorNames/pkg1/DeprMemClass.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +public class DeprMemClass +{ + /** + * Field in the class. + * @deprecated Do not use this field. + */ + public int _field_In_Class; + + public int _fld; + + /** + * Method in the class. + * @deprecated Do not use this method. + */ + public void $method_In_Class() { + } + + public void regularMethod() { + } +} diff --git a/langtools/test/com/sun/javadoc/testAnchorNames/pkg1/RegClass.java b/langtools/test/com/sun/javadoc/testAnchorNames/pkg1/RegClass.java new file mode 100644 index 00000000000..60aae773eb6 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnchorNames/pkg1/RegClass.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +import java.io.Serializable; +import java.util.Map; + +/** + * @serial This is the serial tag's comment. + */ +public class RegClass implements Serializable { + + /** + * Normal field in class. + */ + public String field; + + /** + * Normal field in class. + */ + public String method$$; + + /** + * Filed staring with $. + */ + public String $field; + + /** + * Filed staring with underscore. + */ + public String _field; + + /** + * Serial field + * @serial + */ + public boolean t_e$t; + + /** + * Field in class with a $ in the name. + */ + public String fieldInCla$$; + + /** + * Field name as just an underscore. + */ + public int _; + + /** + * Field name as just a $. + */ + public int $; + + /** + * Field name with underscore and $. + */ + public int _$; + + /** + * Field name with $ and underscore. + */ + public int $_; + + /** + * An array. + */ + public int arr[]; + + /** + * Another array. + */ + public int[] arr1; + + /** + * A constant field. + */ + public static final int S_$$$$$INT = 0; + + /** + * Another field. + */ + public DeprMemClass d____mc; + + /** + * An enum. + */ + public static enum Te$t_Enum { + FLD_1, + $FLD2 + }; + + /** + * A constructor. + */ + public RegClass(String p, int i) { + } + + /** + * Method in Class. + * @param p a string + */ + public void _methodInClass(String p) { + } + + /** + * Method in Class. + * @param p a string + * @param i an int + */ + public void _methodInClas$(String p, int i) { + } + + /** + * Method with $ in the name. + * @param p a string array + */ + public void methodInCla$s(String[] p) { + } + + /** + * Method with D[] as a parameter. + * @param p an array of D + */ + public void methodD(D[] p) { + } + + /** + * Method with $A as a parameter. + * @param p an object of $A + */ + public void methodD($A p) { + } + + /** + * Serial test. + * @serialData This is a serial data comment. + * @return null + */ + protected Object $readResolve(){return null;} + + /** + * Simple method. + */ + public void method() {} + + /** + * Generics. + */ + public static void foo(Map> map) {} + + /** + * A nested class. + */ + public class _NestedClas$ {} + + /** + * Nested class D. + */ + class D {} + + /** + * Nested class $A. + */ + class $A {} +} diff --git a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java index b85f300e81e..b0ff91f7a1f 100644 --- a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,8 @@ /* * @test - * @summary Make sure that annotations types with optional elements has + * @bug 8025633 + * @summary Make sure that annotations types with optional elements have * element headers * @author Mahmood Ali * @library ../lib/ @@ -45,7 +46,7 @@ public class TestAnnotationOptional extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { {BUG_ID + FS + "pkg" + FS + "AnnotationOptional.html", - "" + "" } }; diff --git a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java index 5ffdbab12b2..02286c30245 100644 --- a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java +++ b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4973609 8015249 + * @bug 4973609 8015249 8025633 * @summary Make sure that annotation types with 0 members does not have * extra HR tags. * @author jamieh @@ -45,11 +45,11 @@ public class TestAnnotationTypes extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", - "

  • Summary: 
  • " + NL + "
  • Field | 
  • "}, + "
  • Summary: 
  • " + NL + "
  • Field | 
  • "}, {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", - "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, + "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", ""}, {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", diff --git a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java index 048f2186df5..8b8d3c945c5 100644 --- a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java +++ b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4652655 4857717 + * @bug 4652655 4857717 8025633 * @summary This test verifies that class cross references work properly. * @author jamieh * @library ../lib/ @@ -45,7 +45,7 @@ public class TestClassCrossReferences extends JavadocTester { "Link to external class BigDecimal"}, {BUG_ID + FS + "C.html", - "Link to external member gcd"}, {BUG_ID + FS + "C.html", "
    " + NL + "
    Overrides:
    " + NL + diff --git a/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java b/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java index 78921d49d27..4798cee22ea 100644 --- a/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java +++ b/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java @@ -23,14 +23,13 @@ /* * @test - * @bug 4857717 + * @bug 4857717 8025633 * @summary Test to make sure that externally overriden and implemented methods * are documented properly. The method should still include "implements" or * "overrides" documentation even though the method is external. * @author jamieh * @library ../lib/ - * @build JavadocTester - * @build TestExternalOverridenMethod + * @build JavadocTester TestExternalOverridenMethod * @run main TestExternalOverridenMethod */ @@ -40,13 +39,13 @@ public class TestExternalOverridenMethod extends JavadocTester { private static final String[][] TEST = { {BUG_ID + FS + "pkg" + FS + "XReader.html", "
    Overrides:
    " + NL + - "
    read in class " + "FilterReader
    "}, {BUG_ID + FS + "pkg" + FS + "XReader.html", "
    Specified by:
    " + NL + - "
    readInt in interface " + "DataInput
    "}}; diff --git a/langtools/test/com/sun/javadoc/testHref/TestHref.java b/langtools/test/com/sun/javadoc/testHref/TestHref.java index b8c4a24ca05..8bf6f6e885a 100644 --- a/langtools/test/com/sun/javadoc/testHref/TestHref.java +++ b/langtools/test/com/sun/javadoc/testHref/TestHref.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4663254 8016328 + * @bug 4663254 8016328 8025633 * @summary Verify that spaces do not appear in hrefs and anchors. * @author jamieh * @library ../lib/ @@ -46,31 +46,31 @@ public class TestHref extends JavadocTester { private static final String[][] TEST = { //External link. {BUG_ID + FS + "pkg" + FS + "C1.html", - "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait(long,%20int)\"" + "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\"" }, //Member summary table link. {BUG_ID + FS + "pkg" + FS + "C1.html", - "href=\"../pkg/C1.html#method(int,%20int,%20java.util.ArrayList)\"" + "href=\"../pkg/C1.html#method-int-int-java.util.ArrayList-\"" }, //Anchor test. {BUG_ID + FS + "pkg" + FS + "C1.html", - "" + NL + + "" + NL + "" + NL + "" }, //Backward compatibility anchor test. {BUG_ID + FS + "pkg" + FS + "C1.html", - "" + NL + + "" + NL + "" + NL + "" }, //{@link} test. {BUG_ID + FS + "pkg" + FS + "C2.html", - "Link: " + "Link: " }, //@see test. {BUG_ID + FS + "pkg" + FS + "C2.html", - "See Also:" + NL + "
    " + "See Also:" + NL + "
    " }, //Header does not link to the page itself. diff --git a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java index 755e724dfd9..7d4b28d887a 100644 --- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java +++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java @@ -25,7 +25,7 @@ /* * @test - * @bug 6786690 6820360 + * @bug 6786690 6820360 8025633 * @summary This test verifies the nesting of definition list tags. * @author Bhavesh Patel * @library ../lib/ @@ -64,7 +64,7 @@ public class TestHtmlDefinitionListTag extends JavadocTester { {BUG_ID + FS + "pkg1" + FS + "C1.html", "
    " + NL + "
    Since:
    " + NL + "
    1.4
    " + NL + "
    See Also:
    " + NL + "
    " + - "" + + "" + "setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "pkg1" + FS + "C1.html", "
    "+ NL + "
    Parameters:
    " + NL + "
    title" + " - the title
    " + NL + "
    test - boolean value" + @@ -79,11 +79,11 @@ public class TestHtmlDefinitionListTag extends JavadocTester { "if decorations are to be enabled.
    " + NL + "
    Since:" + "
    " + NL + "
    1.4
    " + NL + "
    See Also:
    " + NL + "
    " + - "readObject()" + + "readObject()" + "
    " + NL + "
    "}, {BUG_ID + FS + "pkg1" + FS + "C1.html", "
    " + NL + "
    Throws:
    " + NL + "
    java.io.IOException
    " + NL + "
    See Also:" + - "
    " + NL + "
    " + + "" + NL + "
    " + "setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "pkg1" + FS + "C2.html", "
    " + NL + "
    Parameters:" + "
    " + NL + "
    set - boolean
    " + NL + "
    " + @@ -91,20 +91,20 @@ public class TestHtmlDefinitionListTag extends JavadocTester { {BUG_ID + FS + "serialized-form.html", "
    " + NL + "
    Throws:" + "
    " + NL + "
    " + "java.io.IOException
    " + NL + "
    See Also:" + - "
    " + NL + "
    " + + "
    " + NL + "
    " + "C1.setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "Deprecated." + " As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + "
    This field indicates whether the C1 is " + "undecorated.
    " + NL + " " + NL + "
    " + NL + "
    Since:
    " + NL + "
    1.4
    " + NL + "
    See Also:" + - "
    " + NL + "
    " + + "" + NL + "
    " + "C1.setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "Deprecated." + " As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + "
    Reads the object stream.
    " + NL + "
    " + NL + "
    Throws:" + @@ -141,29 +141,29 @@ public class TestHtmlDefinitionListTag extends JavadocTester { " if no decorations are" + NL + " to be enabled;" + NL + " false if decorations are to be enabled." + "
    " + NL + "
    Since:
    " + NL + "
    1.4
    " + NL + - "
    See Also:
    " + NL + "
    " + + "
    See Also:
    " + NL + "
    " + "readObject()
    " + NL + "
    "}, {BUG_ID + FS + "pkg1" + FS + "C1.html", "
    " + NL + "
    Throws:" + "
    " + NL + "
    java.io.IOException
    " + NL + "
    " + - "See Also:
    " + NL + "
    " + + "See Also:" + NL + "
    " + "setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "
    " + NL + "
    Throws:" + "
    " + NL + "
    " + "java.io.IOException
    " + NL + "
    See Also:" + - "
    " + NL + "
    " + + "" + NL + "
    " + "C1.setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "Deprecated." + " As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + "
    This field indicates whether the C1 is " + "undecorated.
    " + NL + " " + NL + "
    " + NL + "
    Since:
    " + NL + "
    1.4
    " + NL + "
    See Also:" + - "
    " + NL + "
    " + + "" + NL + "
    " + "C1.setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "Deprecated." + " As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + "
    Reads the object stream.
    " + NL + "
    " + NL + "
    Throws:" + @@ -188,12 +188,12 @@ public class TestHtmlDefinitionListTag extends JavadocTester { {BUG_ID + FS + "serialized-form.html", "
    boolean " +
                      "undecorated
    " + NL + "
    " + "Deprecated. As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean).
    " + NL + ""}, {BUG_ID + FS + "serialized-form.html", "" + "Deprecated. As of JDK version" + " 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + ""}}; // Test for valid HTML generation which should not comprise of empty diff --git a/langtools/test/com/sun/javadoc/testInterface/TestInterface.java b/langtools/test/com/sun/javadoc/testInterface/TestInterface.java index cfaff523fde..39f8e212629 100644 --- a/langtools/test/com/sun/javadoc/testInterface/TestInterface.java +++ b/langtools/test/com/sun/javadoc/testInterface/TestInterface.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4682448 4947464 5029946 + * @bug 4682448 4947464 5029946 8025633 * @summary Verify that the public modifier does not show up in the * documentation for public methods, as recommended by the JLS. * If A implements I and B extends A, B should be in the list of @@ -84,7 +84,7 @@ public class TestInterface extends JavadocTester { //Make sure "Specified By" has substituted type parameters. {BUG_ID + FS + "pkg" + FS + "Child.html", "
    Specified by:
    " + NL + - "
    method" + + "
    method" + " in interface " + "" + "Interface<" + @@ -93,7 +93,7 @@ public class TestInterface extends JavadocTester { //Make sure "Overrides" has substituted type parameters. {BUG_ID + FS + "pkg" + FS + "Child.html", "
    Overrides:
    " + NL + - "
    method" + + "
    method" + " in class Parent<T>
    " diff --git a/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java b/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java index b9374353e26..e2c4a5b2ffc 100644 --- a/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java +++ b/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7112427 8012295 + * @bug 7112427 8012295 8025633 * @summary Test of the JavaFX doclet features. * @author jvalenta * @library ../lib/ @@ -38,8 +38,8 @@ public class TestJavaFX extends JavadocTester { private static final String[][] TEST = new String[][] { {"./" + BUG_ID + "/C.html", - "
    See Also:
    " + NL + "
    getRate(), " + NL + - "setRate(double)
    "}, + "
    See Also:
    " + NL + "
    getRate(), " + NL + + "setRate(double)
    "}, {"./" + BUG_ID + "/C.html", "
    public final void setRate(double value)
    " + NL + "
    Sets the value of the property rate.
    " + NL + @@ -63,7 +63,7 @@ public class TestJavaFX extends JavadocTester { {"./" + BUG_ID + "/C.html", "Property description:"}, {"./" + BUG_ID + "/C.html", - "setTestMethodProperty() " }, + "setTestMethodProperty() " }, {"./" + BUG_ID + "/C.html", "

    isPaused

    " + NL + "
    public final double isPaused()
    " + NL + diff --git a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java index ef9dd2bbb9a..49ce35d0700 100644 --- a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java +++ b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4732864 6280605 7064544 8014636 8016328 + * @bug 4732864 6280605 7064544 8014636 8016328 8025633 * @summary Make sure that you can link from one member to another using * non-qualified name, furthermore, ensure the right one is linked. * @author jamieh @@ -49,9 +49,9 @@ public class TestLinkTaglet extends JavadocTester { "Qualified Link: C.InnerC.
    " + NL + " Unqualified Link1: C.InnerC.
    " + NL + " Unqualified Link2: C.InnerC.
    " + NL + - " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
    " + NL + - " Unqualified Link: method(C.InnerC, C.InnerC2).
    " + NL + - " Unqualified Link: method(InnerC, InnerC2).
    " + " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
    " + NL + + " Unqualified Link: method(C.InnerC, C.InnerC2).
    " + NL + + " Unqualified Link: method(InnerC, InnerC2).
    " }, {BUG_ID + FS + "pkg" + FS + "C.InnerC.html", "Link to member in outer class: C.MEMBER
    " + NL + diff --git a/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java b/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java index 4d90d8791fb..62b9235e952 100644 --- a/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java +++ b/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4638588 4635809 6256068 6270645 + * @bug 4638588 4635809 6256068 6270645 8025633 * @summary Test to make sure that members are inherited properly in the Javadoc. * Verify that inheritence labels are correct. * @author jamieh @@ -44,7 +44,7 @@ public class TestMemberInheritence extends JavadocTester { //Public method should be inherited {BUG_ID + FS + "pkg" + FS + "SubClass.html", - ""}, + ""}, //Public inner class should be inherited. {BUG_ID + FS + "pkg" + FS + "SubClass.html", @@ -56,7 +56,7 @@ public class TestMemberInheritence extends JavadocTester { //Protected method should be inherited {BUG_ID + FS + "pkg" + FS + "SubClass.html", - ""}, + ""}, //Protected inner class should be inherited. {BUG_ID + FS + "pkg" + FS + "SubClass.html", @@ -73,14 +73,14 @@ public class TestMemberInheritence extends JavadocTester { // Test overriding/implementing methods with generic parameters. {BUG_ID + FS + "pkg" + FS + "BaseClass.html", "
    " + NL + "
    Specified by:
    " + NL + - "
    " + + "
    " + "getAnnotation in interface " + "" + "BaseInterface
    " + NL + "
    "}, // Test diamond inheritence member summary (6256068) {BUG_ID + FS + "diamond" + FS + "Z.html", - "aMethod"}, + "aMethod"}, // Test that doc is inherited from closed parent (6270645) {BUG_ID + FS + "inheritDist" + FS + "C.html", @@ -90,7 +90,7 @@ public class TestMemberInheritence extends JavadocTester { private static final String[][] NEGATED_TEST = { {BUG_ID + FS + "pkg" + FS + "SubClass.html", - "staticMethod"}, + "staticMethod
    "}, }; private static final String[] ARGS = new String[] { diff --git a/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java b/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java index fdbb664deff..eff1de42046 100644 --- a/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java +++ b/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4951228 6290760 + * @bug 4951228 6290760 8025633 * @summary Test the case where the overriden method returns a different * type than the method in the child class. Make sure the * documentation is inherited but the return type isn't. @@ -49,7 +49,7 @@ public class TestMemberSummary extends JavadocTester { // Check return type in member summary. {BUG_ID + FS + "pkg" + FS + "PublicChild.html", "PublicChild" + NL + - "" + + "" + "returnTypeTest()" }, // Check return type in member detail. @@ -60,9 +60,9 @@ public class TestMemberSummary extends JavadocTester { // Legacy anchor dimensions (6290760) {BUG_ID + FS + "pkg2" + FS + "A.html", - "" + NL + + "" + NL + "" + NL + - "" + NL + + "" + NL + "" + NL + "" }, diff --git a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java index 4466eb87d0e..d8187147bd2 100644 --- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java +++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4131628 4664607 7025314 8023700 7198273 + * @bug 4131628 4664607 7025314 8023700 7198273 8025633 * @summary Make sure the Next/Prev Class links iterate through all types. * Make sure the navagation is 2 columns, not 3. * @author jamieh @@ -60,7 +60,7 @@ public class TestNavigation extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "I.html", "
  • Next Class
  • "}, // Test for 4664607 {BUG_ID + FS + "pkg" + FS + "I.html", - "" + NL + "" + NL + + "" + NL + "" + NL + "" + NL + ""} }; private static final String[][] NEGATED_TEST = NO_TEST; diff --git a/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java b/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java index 6d44bd64692..37c403eb251 100644 --- a/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java +++ b/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6758050 + * @bug 6758050 8025633 * @summary Test HTML output for nested generic types. * @author bpatel * @library ../lib/ @@ -46,7 +46,7 @@ public class TestNestedGenerics extends JavadocTester { private static final String[][] TEST = { {BUG_ID + FS + "pkg" + FS + "NestedGenerics.html", "" } }; diff --git a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java index ad0e024bfe6..65013120dc8 100644 --- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4789689 4905985 4927164 4827184 4993906 5004549 7025314 7010344 + * @bug 4789689 4905985 4927164 4827184 4993906 5004549 7025314 7010344 8025633 * @summary Run Javadoc on a set of source files that demonstrate new * language features. Check the output to ensure that the new * language features are properly documented. @@ -145,7 +145,7 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "(int... i)"}, {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "(int[][]... i)"}, - {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "(int[]...)"}, + {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "-int:A...-"}, {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "" + "TypeParameters... t"}, @@ -156,13 +156,13 @@ public class TestNewLanguageFeatures extends JavadocTester { //Make sure the summary links are correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", "
  • Summary: 
  • " + NL + "
  • Field | 
  • " + NL + - "
  • " + + "
  • " + "Required | 
  • " + NL + "
  • " + - "Optional
  • "}, + "Optional"}, //Make sure the detail links are correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", "
  • Detail: 
  • " + NL + "
  • Field | 
  • " + NL + - "
  • Element
  • "}, + "
  • Element
  • "}, //Make sure the heading is correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", "Annotation Type AnnotationType"}, @@ -188,16 +188,16 @@ public class TestNewLanguageFeatures extends JavadocTester { //PACKAGE {BUG_ID + FS + "pkg" + FS + "package-summary.html", - "@AnnotationType(optional=\"Package Annotation\"," + NL + - " required=1994)"}, + "@AnnotationType(optional=\"Package Annotation\"," + NL + + " required=1994)"}, //CLASS {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", "
    @AnnotationType(" +
    -                "optional" +
    +                "optional" +
                     "=\"Class Annotation\"," + NL +
    -                "                " +
    +                "                " +
                     "required=1994)" + NL + "public class " +
                     "AnnotationTypeUsage" + NL + "extends java.lang.Object
    "}, @@ -205,36 +205,36 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", "
    @AnnotationType(" +
    -                "optional" +
    +                "optional" +
                     "=\"Field Annotation\"," + NL +
    -                "                " +
    +                "                " +
                     "required=1994)" + NL + "public int field
    "}, //CONSTRUCTOR {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", "
    @AnnotationType(" +
    -                "optional" +
    +                "optional" +
                     "=\"Constructor Annotation\"," + NL +
    -                "                " +
    +                "                " +
                     "required=1994)" + NL + "public AnnotationTypeUsage()
    "}, //METHOD {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", "
    @AnnotationType(" +
    -                "optional" +
    +                "optional" +
                     "=\"Method Annotation\"," + NL +
    -                "                " +
    +                "                " +
                     "required=1994)" + NL + "public void method()
    "}, //METHOD PARAMS {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", "
    public void methodWithParams(" +
                     "" +
    -                "@AnnotationType(" +
    +                "@AnnotationType(" +
                     "optional=\"Parameter Annotation\",required=1994)" + NL +
    +                "href=\"../pkg/AnnotationType.html#required--\">required=1994)" + NL +
                     "                             int documented," + NL +
                     "                             int undocmented)
    "}, @@ -242,9 +242,9 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", "
    public AnnotationTypeUsage(" +
    -                "@AnnotationType(" +
    +                "@AnnotationType(" +
                     "optional=\"Constructor Param Annotation\",required=1994)" + NL +
    +                "href=\"../pkg/AnnotationType.html#required--\">required=1994)" + NL +
                     "                           int documented," + NL +
                     "                           int undocmented)
    "}, @@ -254,43 +254,43 @@ public class TestNewLanguageFeatures extends JavadocTester { //Integer {BUG_ID + FS + "pkg1" + FS + "B.html", - "d=3.14,"}, + "d=3.14,"}, //Double {BUG_ID + FS + "pkg1" + FS + "B.html", - "d=3.14,"}, + "d=3.14,"}, //Boolean {BUG_ID + FS + "pkg1" + FS + "B.html", - "b=true,"}, + "b=true,"}, //String {BUG_ID + FS + "pkg1" + FS + "B.html", - "s=\"sigh\","}, + "s=\"sigh\","}, //Class {BUG_ID + FS + "pkg1" + FS + "B.html", - "c=Foo.class,"}, + "c=Foo.class,"}, //Bounded Class {BUG_ID + FS + "pkg1" + FS + "B.html", - "w=TypeParameterSubClass.class,"}, + "w=TypeParameterSubClass.class,"}, //Enum {BUG_ID + FS + "pkg1" + FS + "B.html", - "e=Penny,"}, + "e=Penny,"}, //Annotation Type {BUG_ID + FS + "pkg1" + FS + "B.html", - "a=@AnnotationType(optional=\"foo\",required=1994),"}, + "a=@AnnotationType(optional=\"foo\",required=1994),"}, //String Array {BUG_ID + FS + "pkg1" + FS + "B.html", - "sa={\"up\",\"down\"},"}, + "sa={\"up\",\"down\"},"}, //Primitive {BUG_ID + FS + "pkg1" + FS + "B.html", - "primitiveClassTest=boolean.class,"}, + "primitiveClassTest=boolean.class,"}, //XXX: Add array test case after this if fixed: //5020899: Incorrect internal representation of class-valued annotation elements @@ -335,7 +335,7 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", "ClassUseTest1." + "method" + + "ClassUseTest1.html#method-T-\">method" + "(T t) " }, {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", @@ -388,7 +388,7 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo2.html", "" + "ClassUseTest1.method" + + "pkg2/ClassUseTest1.html#method-T-\">method" + "(T t) " }, @@ -417,7 +417,7 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", "ClassUseTest2." + "method" + + "ClassUseTest2.html#method-T-\">method" + "(T t) " }, {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", @@ -472,7 +472,7 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", "ClassUseTest2." + "method" + + "ClassUseTest2.html#method-T-\">method" + "(T t) " }, {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", @@ -517,7 +517,7 @@ public class TestNewLanguageFeatures extends JavadocTester { {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", "ClassUseTest3" + ".method(T t) " + "html#method-T-\">method(T t)
     " }, {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", "<T extends ClassUseTest3." + "method(T t)" + + "html#method-T-\">method(T t)" + " " }, {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", @@ -588,7 +588,7 @@ public class TestNewLanguageFeatures extends JavadocTester { "void" + NL + "ClassUseTest3." + "method(java." + + "html#method-java.util.Set-\">method(java." + "util.Set<Foo4> p) " + NL + "" + NL + "" @@ -663,14 +663,14 @@ public class TestNewLanguageFeatures extends JavadocTester { // TYPE PARAMETER IN INDEX //================================= {BUG_ID + FS + "index-all.html", - "" + + "" + "method(Vector<Object>)" }, //================================= // TYPE PARAMETER IN INDEX //================================= {BUG_ID + FS + "index-all.html", - "" + + "" + "method(Vector<Object>)" }, }; diff --git a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java index 68999480d44..506fde14a71 100644 --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4368820 + * @bug 4368820 8025633 * @summary Inherited comment should link directly to member, not just * class * @author jamieh @@ -47,7 +47,7 @@ public class TestOverridenMethodDocCopy extends JavadocTester { private static final String[][] TEST = { {BUG_ID + FS + "pkg1" + FS + "SubClass.html", "Description copied from class: " + - "" + + "" + "BaseClass" } }; diff --git a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPackageFlag.java b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPackageFlag.java index 702c54c8309..018f04a2817 100644 --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPackageFlag.java +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPackageFlag.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4634891 + * @bug 4634891 8025633 * @summary Determine if overriden methods are properly documented when * -protected (default) visibility flag is used. * @author jamieh @@ -41,14 +41,14 @@ public class TestOverridenPrivateMethodsWithPackageFlag extends JavadocTester { //The public method should be overriden {BUG_ID + FS + "pkg1" + FS + "SubClass.html", "
    Overrides:
    " + NL + - "
    " + + "
    " + "publicMethod in class " + "BaseClass
    "}, //The public method in different package should be overriden {BUG_ID + FS + "pkg2" + FS + "SubClass.html", "
    Overrides:
    " + NL + - "
    " + + "
    " + "publicMethod in class " + "BaseClass
    "}, @@ -56,7 +56,7 @@ public class TestOverridenPrivateMethodsWithPackageFlag extends JavadocTester { //package. {BUG_ID + FS + "pkg1" + FS + "SubClass.html", "
    Overrides:
    " + NL + - "
    " + + "
    " + "packagePrivateMethod in class " + "BaseClass
    "} }; diff --git a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java index b7a9bc73a10..6da9e9c1df7 100644 --- a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java +++ b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4780441 4874845 4978816 8014017 8016328 + * @bug 4780441 4874845 4978816 8014017 8016328 8025633 * @summary Make sure that when the -private flag is not used, members * inherited from package private class are documented in the child. * @@ -66,7 +66,7 @@ public class TestPrivateClasses extends JavadocTester { // Method inheritence from non-public superclass. {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", - "" + + "" + "methodInheritedFromParent" }, @@ -78,7 +78,7 @@ public class TestPrivateClasses extends JavadocTester { // Method inheritence from non-public superinterface. {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", - "" + + "" + "methodInterface" }, @@ -139,7 +139,7 @@ public class TestPrivateClasses extends JavadocTester { //Do not inherit private interface method with generic parameters. //This method has been implemented. {BUG_ID + "-1" + FS + "pkg2" + FS + "C.html", - "hello"}, + "hello"}, }; // Test output when -private flag is used. @@ -171,20 +171,20 @@ public class TestPrivateClasses extends JavadocTester { "PrivateParent" }, {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", - "" + + "" + "methodInheritedFromParent" }, // Should document that a method overrides method from private class. {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", "
    Overrides:
    " + NL + - "
    " + + "
    " + "methodOverridenFromParent in class " + "" + "PrivateParent
    "}, // Should document that a method is specified by private interface. {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", "
    Specified by:
    " + NL + - "
    " + + "
    " + "methodInterface in interface " + "" + "PrivateInterface
    "}, @@ -195,7 +195,7 @@ public class TestPrivateClasses extends JavadocTester { "PrivateInterface" }, {BUG_ID + "-2" + FS + "pkg" + FS + "PrivateInterface.html", - "" + + "" + "methodInterface" }, // Should mention that any documentation was copied. @@ -228,11 +228,11 @@ public class TestPrivateClasses extends JavadocTester { //with generic parameters has been implemented. {BUG_ID + "-2" + FS + "pkg2" + FS + "C.html", "Description copied from interface: " + - "I"}, + "I"}, {BUG_ID + "-2" + FS + "pkg2" + FS + "C.html", "
    Specified by:
    " + NL + - "
    hello" + + "
    hello" + " in interface " + "I" + "<java.lang.String>
    "}, diff --git a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java index 760d24af458..06217b94a56 100644 --- a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java +++ b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java @@ -25,7 +25,7 @@ /* * @test - * @bug 6802694 + * @bug 6802694 8025633 * @summary This test verifies deprecation info in serialized-form.html. * @author Bhavesh Patel * @library ../lib/ @@ -44,21 +44,21 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester { {BUG_ID + FS + "serialized-form.html", "
    " + NL + "
    Throws:
    " + NL + "
    " + "java.io.IOException
    "+ NL + "
    See Also:" + - "
    " + NL + "
    " + + "" + NL + "
    " + "C1.setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "Deprecated." + " As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + "
    This field indicates whether the C1 " + "is undecorated.
    " + NL + " " + NL + "
    " + NL + "
    Since:
    " + NL + "
    1.4
    " + NL + "
    See Also:" + - "
    " + NL + "
    " + + "" + NL + "
    " + "C1.setUndecorated(boolean)
    " + NL + "
    "}, {BUG_ID + FS + "serialized-form.html", "Deprecated." + " As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + "
    Reads the object stream.
    " + NL + "
    " + NL + "
    Throws:
    " + NL + "
    " + @@ -75,12 +75,12 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester { {BUG_ID + FS + "serialized-form.html", "
    boolean undecorated
    " + NL + "
    Deprecated. " + "As of JDK version 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean).
    " + NL + ""}, {BUG_ID + FS + "serialized-form.html", "" + "Deprecated. As of JDK version" + " 1.5, replaced by" + NL + - " " + + " " + "setUndecorated(boolean)." + NL + ""}}; // Test with -nodeprecated option. The serialized-form.html should diff --git a/langtools/test/com/sun/javadoc/testTaglets/TestTaglets.java b/langtools/test/com/sun/javadoc/testTaglets/TestTaglets.java index 53461390e52..e49e857e6fe 100644 --- a/langtools/test/com/sun/javadoc/testTaglets/TestTaglets.java +++ b/langtools/test/com/sun/javadoc/testTaglets/TestTaglets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4654308 4767038 + * @bug 4654308 4767038 8025633 * @summary Use a Taglet and include some inline tags such as {@link}. The * inline tags should be interpreted properly. * Run Javadoc on some sample source that uses {@inheritDoc}. Make @@ -56,7 +56,7 @@ public class TestTaglets extends JavadocTester { //Input for string search tests. private static final String[][] TEST_4654308 = new String[][] { {"4654308" + FS + "C.html", "Foo:" + - "
    my only method is here" + + "
    my only method is here" + "
    "} }; private static final String[][] NEGATED_TEST_4654308 = NO_TEST; diff --git a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java index 61d5758bb5d..d1eb1179aee 100644 --- a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java +++ b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8005091 8009686 + * @bug 8005091 8009686 8025633 * @summary Make sure that type annotations are displayed correctly * @author Bhavesh Patel * @library ../lib/ @@ -272,13 +272,13 @@ public class TestTypeAnnotations extends JavadocTester { "
    void oneException()" + NL +
                 "           throws @ThrB(value=\"m\") java.lang.Exception
    " + "ThrB.html#value--\">value=\"m\") java.lang.Exception" }, {BUG_ID + FS + "typeannos" + FS + "ThrWithValue.html", "
    void twoExceptions()" + NL +
                 "            throws @ThrB(value=\"m\") java.lang.RuntimeException," + NL +
    +            "ThrB.html#value--\">value=\"m\") java.lang.RuntimeException," + NL +
                 "                   @ThrA java.lang.Exception
    " }, @@ -307,14 +307,14 @@ public class TestTypeAnnotations extends JavadocTester { "
    void wcSuper(MyList<? super @WldB(value=\"m\") java.lang." +
    +            "../typeannos/WldB.html#value--\">value=\"m\") java.lang." +
                 "String> l)
    " }, {BUG_ID + FS + "typeannos" + FS + "BoundWithValue.html", "
    MyList<? extends @WldB(value=\"m\") java.lang.String" +
    +            "typeannos/WldB.html#value--\">value=\"m\") java.lang.String" +
                 "> returnWcExtends()
    " }, @@ -329,7 +329,7 @@ public class TestTypeAnnotations extends JavadocTester { "
    java.lang.String nonVoid(@RcvrA @RcvrB" +
    -            "(value=\"m\")" +
    +            "(value=\"m\")" +
                 " DefaultUnmodified this)
    " }, {BUG_ID + FS + "typeannos" + FS + "DefaultUnmodified.html", @@ -354,7 +354,7 @@ public class TestTypeAnnotations extends JavadocTester { {BUG_ID + FS + "typeannos" + FS + "WithValue.html", "
    <T extends java.lang.Runnable> void accept(" +
                 "@RcvrB(" +
    +            "typeannos\">@RcvrB(" +
                 "value=\"m\") WithValue this," + NL +
                 "                                           T r)" + NL +
                 "                                    throws java.lang.Exception
    " @@ -362,7 +362,7 @@ public class TestTypeAnnotations extends JavadocTester { {BUG_ID + FS + "typeannos" + FS + "WithFinal.html", "
    java.lang.String nonVoid(@RcvrB(value=\"m\") WithFinal" +
    +            "typeannos/RcvrB.html#value--\">value=\"m\") WithFinal" +
                 " this)
    " }, {BUG_ID + FS + "typeannos" + FS + "WithBody.html", diff --git a/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java b/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java index ee352a1b385..14e7ba47a6a 100644 --- a/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java +++ b/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4927167 4974929 7010344 + * @bug 4927167 4974929 7010344 8025633 * @summary When the type parameters are more than 10 characters in length, * make sure there is a line break between type params and return type * in member summary. Also, test for type parameter links in package-summary and @@ -71,7 +71,7 @@ public class TestTypeParameters extends JavadocTester { }, //Nested type parameters {BUG_ID + FS + "pkg" + FS + "C.html", - "" + NL + + "" + NL + "" + NL + "" }, diff --git a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java index d5f697a213e..7152cced990 100644 --- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java +++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4515705 4804296 4702454 4697036 + * @bug 4515705 4804296 4702454 4697036 8025633 * @summary Make sure that first sentence warning only appears once. * Make sure that only warnings/errors are printed when quiet is used. * Make sure that links to private/unincluded methods do not cause @@ -65,8 +65,8 @@ public class TestWarnings extends JavadocTester { }; private static final String[][] TEST2 = { - {BUG_ID + FS + "pkg" + FS + "X.html", "m()
    "}, - {BUG_ID + FS + "pkg" + FS + "X.html", "X()
    "}, + {BUG_ID + FS + "pkg" + FS + "X.html", "m()
    "}, + {BUG_ID + FS + "pkg" + FS + "X.html", "X()
    "}, {BUG_ID + FS + "pkg" + FS + "X.html", "f
    "}, }; From ad8c918fb18c56b9c27267d804142c39eeb2e1f7 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Thu, 10 Oct 2013 13:55:41 -0400 Subject: [PATCH 044/152] 8019461: Clean up javac diagnostics 7196553: Review error messages for repeating annotations Changes to the diagnostic messages to improve clarity and JLS coherence Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Attr.java | 21 +++-- .../com/sun/tools/javac/comp/Check.java | 7 +- .../com/sun/tools/javac/comp/MemberEnter.java | 19 +++-- .../tools/javac/resources/compiler.properties | 78 ++++++++++--------- .../examples/InterfaceOrArrayExpected.java | 28 +++++++ ...=> RepeatableAnnotationsNotSupported.java} | 4 +- 6 files changed, 101 insertions(+), 56 deletions(-) create mode 100644 langtools/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java rename langtools/test/tools/javac/diags/examples/{DuplicateAnnotation.java => RepeatableAnnotationsNotSupported.java} (91%) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 3b840409696..090ea9c3039 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -792,17 +792,19 @@ public class Attr extends JCTree.Visitor { Type t = tree.type != null ? tree.type : attribType(tree, env); - return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); + return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible); } Type checkBase(Type t, JCTree tree, Env env, boolean classExpected, - boolean interfaceOrArrayExpected, + boolean interfacesOnlyExpected, + boolean interfacesOrArraysExpected, boolean checkExtensible) { if (t.isErroneous()) return t; - if (t.hasTag(TYPEVAR) && !classExpected && !interfaceOrArrayExpected) { + if (t.hasTag(TYPEVAR) && !classExpected && + !interfacesOrArraysExpected && !interfacesOnlyExpected) { // check that type variable is already visible if (t.getUpperBound() == null) { log.error(tree.pos(), "illegal.forward.ref"); @@ -814,12 +816,17 @@ public class Attr extends JCTree.Visitor { t = chk.checkClassOrArrayType(tree.pos(), t, checkExtensible|!allowGenerics); } - if (interfaceOrArrayExpected && - !(t.tsym.isInterface() || t.getTag() == ARRAY)) { + if (interfacesOnlyExpected && !t.tsym.isInterface()) { log.error(tree.pos(), "intf.expected.here"); // return errType is necessary since otherwise there might // be undetected cycles which cause attribution to loop return types.createErrorType(t); + } else if (interfacesOrArraysExpected && + !(t.tsym.isInterface() || t.getTag() == ARRAY)) { + log.error(tree.pos(), "intf.or.array.expected.here"); + // return errType is necessary since otherwise there might + // be undetected cycles which cause attribution to loop + return types.createErrorType(t); } else if (checkExtensible && classExpected && t.tsym.isInterface()) { @@ -3988,7 +3995,7 @@ public class Attr extends JCTree.Visitor { Set boundSet = new HashSet(); if (bounds.nonEmpty()) { // accept class or interface or typevar as first bound. - bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); + bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false); boundSet.add(types.erasure(bounds.head.type)); if (bounds.head.type.isErroneous()) { return bounds.head.type; @@ -4004,7 +4011,7 @@ public class Attr extends JCTree.Visitor { // if first bound was a class or interface, accept only interfaces // as further bounds. for (JCExpression bound : bounds.tail) { - bound.type = checkBase(bound.type, bound, env, false, true, false); + bound.type = checkBase(bound.type, bound, env, false, false, true, false); if (bound.type.isErroneous()) { bounds = List.of(bound); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 720b150bc68..e86ecc90ea6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -3420,15 +3420,14 @@ public class Check { sym.name != names.error && (!staticImport || !e.isStaticallyImported())) { if (!e.sym.type.isErroneous()) { - String what = e.sym.toString(); if (!isClassDecl) { if (staticImport) - log.error(pos, "already.defined.static.single.import", what); + log.error(pos, "already.defined.static.single.import", e.sym); else - log.error(pos, "already.defined.single.import", what); + log.error(pos, "already.defined.single.import", e.sym); } else if (sym != e.sym) - log.error(pos, "already.defined.this.unit", what); + log.error(pos, "already.defined.this.unit", e.sym); } return false; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index fbb8c326889..d611fbac7e8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -114,12 +114,15 @@ public class MemberEnter extends JCTree.Visitor implements Completer { deferredLintHandler = DeferredLintHandler.instance(context); lint = Lint.instance(context); allowTypeAnnos = source.allowTypeAnnotations(); + allowRepeatedAnnos = source.allowRepeatedAnnotations(); } /** Switch: support type annotations. */ boolean allowTypeAnnos; + boolean allowRepeatedAnnos; + /** A queue for classes whose members still need to be entered into the * symbol table. */ @@ -906,14 +909,14 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } if (annotated.containsKey(a.type.tsym)) { - if (source.allowRepeatedAnnotations()) { - ListBuffer l = annotated.get(a.type.tsym); - l = l.append(c); - annotated.put(a.type.tsym, l); - pos.put(c, a.pos()); - } else { - log.error(a.pos(), "duplicate.annotation"); + if (!allowRepeatedAnnos) { + log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); + allowRepeatedAnnos = true; } + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(c); + annotated.put(a.type.tsym, l); + pos.put(c, a.pos()); } else { annotated.put(a.type.tsym, ListBuffer.of(c)); pos.put(c, a.pos()); @@ -1197,7 +1200,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { annotated.put(a.type.tsym, l); pos.put(tc, a.pos()); } else { - log.error(a.pos(), "duplicate.annotation"); + log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); } } else { annotated.put(a.type.tsym, ListBuffer.of(tc)); diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 2fc6ab75a80..9e4701522ea 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -78,26 +78,26 @@ compiler.err.already.defined.in.clinit=\ # 0: string compiler.err.already.defined.single.import=\ - {0} is already defined in a single-type import + a type with the same simple name is already defined by the single-type-import of {0} # 0: string compiler.err.already.defined.static.single.import=\ - {0} is already defined in a static single-type import + a type with the same simple name is already defined by the static single-type-import of {0} compiler.err.already.defined.this.unit=\ {0} is already defined in this compilation unit # 0: type, 1: list of name compiler.err.annotation.missing.default.value=\ - annotation {0} is missing value for the attribute {1} + annotation @{0} is missing a default value for the element ''{1}'' # 0: type, 1: list of name compiler.err.annotation.missing.default.value.1=\ - annotation {0} is missing values for attributes {1} + annotation @{0} is missing default values for elements {1} # 0: type compiler.err.annotation.not.valid.for.type=\ - annotation not valid for a value of type {0} + annotation not valid for an element of type {0} compiler.err.annotation.type.not.applicable=\ annotation type not applicable to this kind of declaration @@ -135,7 +135,7 @@ compiler.err.array.req.but.found=\ array required, but {0} found compiler.err.attribute.value.must.be.constant=\ - attribute value must be constant + element value must be a constant expression # 0: statement type compiler.err.bad.initializer=\ @@ -298,8 +298,9 @@ compiler.err.cont.outside.loop=\ compiler.err.cyclic.inheritance=\ cyclic inheritance involving {0} +# 0: symbol compiler.err.cyclic.annotation.element=\ - cyclic annotation element type + type of element {0} is cyclic # 0: unused compiler.err.call.to.super.not.allowed.in.enum.ctor=\ @@ -307,73 +308,70 @@ compiler.err.call.to.super.not.allowed.in.enum.ctor=\ # 0: type compiler.err.no.superclass=\ - {0} has no superclass + {0} has no superclass. # 0: symbol, 1: type, 2: symbol, 3: type, 4: unused compiler.err.concrete.inheritance.conflict=\ methods {0} from {1} and {2} from {3} are inherited with the same signature compiler.err.default.allowed.in.intf.annotation.member=\ - default value only allowed in an @interface member + default value only allowed in an annotation type declaration # 0: symbol compiler.err.doesnt.exist=\ package {0} does not exist -compiler.err.duplicate.annotation=\ - duplicate annotation - # 0: type compiler.err.duplicate.annotation.invalid.repeated=\ - annotation {0} cannot be repeated\nIt does not define a valid containing annotation. + annotation {0} is not a valid repeatable annotation # 0: name, 1: type compiler.err.duplicate.annotation.member.value=\ - duplicate annotation member value {0} in {1} + duplicate element ''{0}'' in annotation @{1}. -# 0: type, 1: type +# 0: name, 1: unused compiler.err.duplicate.annotation.missing.container=\ - duplicate annotation: the declaration of {0} does not have a valid {1} annotation + {0} is not a repeatable annotation type -# 0: type +# 0: type, 1: unused compiler.err.invalid.repeatable.annotation=\ - duplicate annotation: {0} is annotated with an invalid Repeatable annotation + duplicate annotation: {0} is annotated with an invalid @Repeatable annotation # 0: symbol or type compiler.err.invalid.repeatable.annotation.no.value=\ - duplicate annotation: {0} is not a valid Repeatable, no value element method declared + {0} is not a valid @Repeatable, no value element method declared # 0: type, 1: number compiler.err.invalid.repeatable.annotation.multiple.values=\ - duplicate annotation: {0} is not a valid Repeatable, {1} value element methods declared + {0} is not a valid @Repeatable, {1} element methods named ''value'' declared # 0: type compiler.err.invalid.repeatable.annotation.invalid.value=\ - duplicate annotation: {0} is not a valid Repeatable: invalid value element + {0} is not a valid @Repeatable: invalid value element -# 0: symbol type, 1: type, 2: type +# 0: symbol type, 1: unused, 2: type compiler.err.invalid.repeatable.annotation.value.return=\ - duplicate annotation: value element of containing annotation {0} should have type {2}, found {1} + containing annotation type ({0}) must declare an element named ''value'' of type {2} # 0: symbol or type, 1: symbol compiler.err.invalid.repeatable.annotation.elem.nondefault=\ - containing annotation {0} does not have a default value for element {1} + containing annotation type ({0}) does not have a default value for element {1} -# 0: symbol, 1: type, 2: symbol, 3: type +# 0: symbol, 1: unused, 2: symbol, 3: unused compiler.err.invalid.repeatable.annotation.retention=\ - containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3} + retention of containing annotation type ({0}) is shorter than the retention of repeatable annotation type ({2}) # 0: symbol, 1: symbol compiler.err.invalid.repeatable.annotation.not.documented=\ - containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is + repeatable annotation type ({1}) is @Documented while containing annotation type ({0}) is not # 0: symbol, 1: symbol compiler.err.invalid.repeatable.annotation.not.inherited=\ - containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is + repeatable annotation type ({1}) is @Inherited while containing annotation type ({0}) is not # 0: symbol, 1: symbol compiler.err.invalid.repeatable.annotation.incompatible.target=\ - target of container annotation {0} is not a subset of target of repeated annotation {1} + containing annotation type ({0}) is applicable to more targets than repeatable annotation type ({1}) # 0: symbol compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\ @@ -561,26 +559,31 @@ compiler.err.int.number.too.large=\ integer number too large: {0} compiler.err.intf.annotation.members.cant.have.params=\ - @interface members may not have parameters + elements in annotation type declarations cannot declare formal parameters +# 0: symbol compiler.err.intf.annotation.cant.have.type.params=\ - @interface may not have type parameters + annotation type {0} cannot be generic compiler.err.intf.annotation.members.cant.have.type.params=\ - @interface members may not have type parameters + elements in annotation type declarations cannot be generic methods # 0: symbol, 1: type compiler.err.intf.annotation.member.clash=\ - @interface member clashes with method ''{0}'' in {1} + annotation type {1} declares an element with the same name as method {0} compiler.err.intf.expected.here=\ interface expected here +compiler.err.intf.or.array.expected.here=\ + interface or array type expected here + compiler.err.intf.meth.cant.have.body=\ interface abstract methods cannot have body +# 0: symbol compiler.err.invalid.annotation.member.type=\ - invalid type for annotation member + invalid type for element {0} of annotation type compiler.err.invalid.binary.number=\ binary numbers must contain at least one binary digit @@ -2309,9 +2312,14 @@ compiler.err.type.annotations.not.supported.in.source=\ type annotations are not supported in -source {0}\n\ (use -source 8 or higher to enable type annotations) +# 0: string +compiler.err.repeatable.annotations.not.supported.in.source=\ + repeated annotations are not supported in -source {0}\n\ +(use -source 8 or higher to enable repeated annotations) + # 0: string compiler.err.foreach.not.supported.in.source=\ - for-each loops are not supported in -source {0}\n\ + enhanced for loops are not supported in -source {0}\n\ (use -source 5 or higher to enable for-each loops) # 0: string diff --git a/langtools/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java b/langtools/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java new file mode 100644 index 00000000000..4c57562958e --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.intf.or.array.expected.here + +import java.util.List; + +class InterfaceExpected { } diff --git a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java b/langtools/test/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java similarity index 91% rename from langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java rename to langtools/test/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java index 1301f4e694e..2d84ed0267f 100644 --- a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java @@ -21,7 +21,7 @@ * questions. */ -// key: compiler.err.duplicate.annotation +// key: compiler.err.repeatable.annotations.not.supported.in.source // key: compiler.warn.source.no.bootclasspath // options: -source 7 @@ -29,4 +29,4 @@ @Anno @Anno -class DuplicateAnnotation { } +class RepeatableAnnotationsNotSupported { } From 66bb0d28fac3b63f6a537daa91ee0fd1d7005b66 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 10 Oct 2013 21:43:35 +0200 Subject: [PATCH 045/152] 8026264: Getter, setter function name mangling issues Reviewed-by: lagergren, jlaskey --- .../jdk/nashorn/internal/parser/Parser.java | 4 +- .../RecompilableScriptFunctionData.java | 19 +++++-- nashorn/test/script/basic/JDK-8026264.js | 54 +++++++++++++++++++ 3 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026264.js diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index 61c70d956c7..c19d4367c7a 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -2113,7 +2113,7 @@ loop: case "get": final PropertyKey getIdent = propertyName(); final String getterName = getIdent.getPropertyName(); - final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + NameCodec.encode(getterName)); + final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName)); expect(LPAREN); expect(RPAREN); functionNode = functionBody(getSetToken, getNameNode, new ArrayList(), FunctionNode.Kind.GETTER); @@ -2122,7 +2122,7 @@ loop: case "set": final PropertyKey setIdent = propertyName(); final String setterName = setIdent.getPropertyName(); - final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + NameCodec.encode(setterName)); + final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName)); expect(LPAREN); final IdentNode argIdent = getIdent(); verifyStrictIdent(argIdent, "setter argument"); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java index fee049707f1..ef9324d9d6e 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java @@ -33,6 +33,7 @@ import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; +import jdk.internal.dynalink.support.NameCodec; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.CompilerConstants; @@ -100,9 +101,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData { * @param allocatorMap allocator map to seed instances with, when constructing */ public RecompilableScriptFunctionData(final FunctionNode functionNode, final CodeInstaller installer, final String allocatorClassName, final PropertyMap allocatorMap) { - super(functionNode.isAnonymous() ? - "" : - functionNode.getIdent().getName(), + super(functionName(functionNode), functionNode.getParameters().size(), functionNode.isStrict(), false, @@ -139,6 +138,20 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData { return sb.toString() + super.toString(); } + private static String functionName(final FunctionNode fn) { + if (fn.isAnonymous()) { + return ""; + } else { + final FunctionNode.Kind kind = fn.getKind(); + if (kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) { + final String name = NameCodec.decode(fn.getIdent().getName()); + return name.substring(4); // 4 is "get " or "set " + } else { + return fn.getIdent().getName(); + } + } + } + private static long tokenFor(final FunctionNode fn) { final int position = Token.descPosition(fn.getFirstToken()); final int length = Token.descPosition(fn.getLastToken()) - position + Token.descLength(fn.getLastToken()); diff --git a/nashorn/test/script/basic/JDK-8026264.js b/nashorn/test/script/basic/JDK-8026264.js new file mode 100644 index 00000000000..b4de01d2adf --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026264.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026264: Getter, setter function name mangling issues + * + * @test + * @run + */ + +var obj = { + get ":"(){}, + set ":"(x){}, + get ""(){}, + set ""(x){} +}; + +var desc = Object.getOwnPropertyDescriptor(obj, ":"); +if (desc.get.name != ':') { + fail("getter name is expected to be ':' got " + desc.get.name); +} + +if (desc.set.name != ':') { + fail("setter name is expected to be ':' got " + desc.set.name); +} + +desc = Object.getOwnPropertyDescriptor(obj, ""); +if (desc.get.name != '') { + fail("getter name is expected to be '' got " + desc.get.name); +} + +if (desc.set.name != '') { + fail("setter name is expected to be '' got " + desc.set.name); +} From ea3f63b0968afe6a1dcdcfdebd341fc374e4231f Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Thu, 10 Oct 2013 17:01:05 -0700 Subject: [PATCH 046/152] 8003262: reverse translation required changes in xalan resource bundles Reviewed-by: lancea, dfuchs --- .../xalan/internal/res/XSLTErrorResources.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_de.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_es.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_fr.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_it.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_ja.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_ko.java | 15 +++++++-------- .../internal/res/XSLTErrorResources_pt_BR.java | 15 +++++++-------- .../xalan/internal/res/XSLTErrorResources_sv.java | 15 +++++++-------- .../internal/res/XSLTErrorResources_zh_CN.java | 15 +++++++-------- .../internal/res/XSLTErrorResources_zh_TW.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_ca.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_cs.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_de.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_es.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_fr.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_it.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_ja.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_ko.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_pt_BR.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_sk.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_sv.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_zh_CN.java | 15 +++++++-------- .../xsltc/compiler/util/ErrorMessages_zh_TW.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_ca.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_cs.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_de.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_es.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_fr.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_it.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_ja.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_ko.java | 15 +++++++-------- .../xsltc/runtime/ErrorMessages_pt_BR.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_sk.java | 15 +++++++-------- .../internal/xsltc/runtime/ErrorMessages_sv.java | 15 +++++++-------- .../xsltc/runtime/ErrorMessages_zh_CN.java | 15 +++++++-------- .../xsltc/runtime/ErrorMessages_zh_TW.java | 15 +++++++-------- 39 files changed, 273 insertions(+), 312 deletions(-) diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java index aea4fffa668..1a85fc3ba9b 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java @@ -471,7 +471,13 @@ public class XSLTErrorResources extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_de.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_de.java index 40a5c714b03..c9cea1d299c 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_de.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_de.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_de extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_de extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_es.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_es.java index 9937fe6b51d..7294a36feeb 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_es.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_es.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_es extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_es extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_fr.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_fr.java index 9dc7f691a88..1748506a255 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_fr.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_fr.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_fr extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_fr extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_it.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_it.java index 2d7351cf4d0..d25eb67d962 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_it.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_it.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_it extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_it extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ja.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ja.java index e5c25673227..50028e76907 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ja.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ja.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_ja extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_ja extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ko.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ko.java index 36203fb8f0f..d4b9b32b3b3 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ko.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ko.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_ko extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_ko extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_pt_BR.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_pt_BR.java index ae6f6c7b312..b79cfabe162 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_pt_BR.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_pt_BR.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_pt_BR extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_pt_BR extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_sv.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_sv.java index 999092d231c..53e943cce24 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_sv.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_sv.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_sv extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_sv extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_CN.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_CN.java index c42b6f3a6f4..3c4544056ec 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_CN.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_CN.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_zh_CN extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_zh_CN extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_TW.java b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_TW.java index 317ee2013e7..a842dfa8020 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_TW.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_TW.java @@ -471,7 +471,13 @@ public class XSLTErrorResources_zh_TW extends ListResourceBundle // Error messages... - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /** Error message ID that has a null message, but takes in a single object. */ {"ER0000" , "{0}" }, @@ -1412,13 +1418,6 @@ public class XSLTErrorResources_zh_TW extends ListResourceBundle }; - /** Get the lookup table for error messages. - * - * @return The int to message lookup table. - */ - public Object[][] getContents() - { - return _contents; } // ================= INFRASTRUCTURE ====================== diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java index 8595d82bc21..500c3fce26a 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java @@ -90,7 +90,13 @@ public class ErrorMessages extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "More than one stylesheet defined in the same file."}, @@ -1012,12 +1018,5 @@ public class ErrorMessages extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java index fa28ddc2d2f..708f7444b89 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java @@ -90,7 +90,13 @@ public class ErrorMessages_ca extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "S'ha definit m\u00e9s d'un full d'estils en el mateix fitxer."}, @@ -853,12 +859,5 @@ public class ErrorMessages_ca extends ListResourceBundle { "FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present."} }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java index 4220efd8f04..f172643766d 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java @@ -90,7 +90,13 @@ public class ErrorMessages_cs extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "V\u00edce ne\u017e jedna p\u0159edloha stylu je definov\u00e1na ve stejn\u00e9m souboru."}, @@ -853,12 +859,5 @@ public class ErrorMessages_cs extends ListResourceBundle { "FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present."} }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java index 48c3b6d1466..9807d06f41c 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java @@ -90,7 +90,13 @@ public class ErrorMessages_de extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Mehrere Stylesheets in derselben Datei definiert."}, @@ -964,12 +970,5 @@ public class ErrorMessages_de extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java index 46e69aaf1b1..1225bd9cfbe 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java @@ -90,7 +90,13 @@ public class ErrorMessages_es extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Se ha definido m\u00E1s de una hoja de estilo en el mismo archivo."}, @@ -964,12 +970,5 @@ public class ErrorMessages_es extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java index 6d68f2479bd..588e02df1ad 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java @@ -90,7 +90,13 @@ public class ErrorMessages_fr extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Plusieurs feuilles de style d\u00E9finies dans le m\u00EAme fichier."}, @@ -964,12 +970,5 @@ public class ErrorMessages_fr extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java index 32872e75d30..030ea71a00a 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java @@ -90,7 +90,13 @@ public class ErrorMessages_it extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Sono stati definiti pi\u00F9 fogli di stile nello stesso file."}, @@ -964,12 +970,5 @@ public class ErrorMessages_it extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java index 7507e5d7287..efd13271a2e 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java @@ -90,7 +90,13 @@ public class ErrorMessages_ja extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "\u540C\u3058\u30D5\u30A1\u30A4\u30EB\u306B\u8907\u6570\u306E\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u304C\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059\u3002"}, @@ -964,12 +970,5 @@ public class ErrorMessages_ja extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java index dc0d6c3d67f..3921af4e764 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java @@ -90,7 +90,13 @@ public class ErrorMessages_ko extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "\uB3D9\uC77C\uD55C \uD30C\uC77C\uC5D0 \uC2A4\uD0C0\uC77C\uC2DC\uD2B8\uAC00 \uB450 \uAC1C \uC774\uC0C1 \uC815\uC758\uB418\uC5C8\uC2B5\uB2C8\uB2E4."}, @@ -964,12 +970,5 @@ public class ErrorMessages_ko extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java index 274a4a0f5bd..6760941be9d 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java @@ -90,7 +90,13 @@ public class ErrorMessages_pt_BR extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Mais de uma folha de estilos definida no mesmo arquivo."}, @@ -964,12 +970,5 @@ public class ErrorMessages_pt_BR extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java index 1a76afc2403..17646e9c51d 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java @@ -90,7 +90,13 @@ public class ErrorMessages_sk extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Viac ne\u017e jeden \u0161t\u00fdl dokumentu bol definovan\u00fd v rovnakom s\u00fabore."}, @@ -853,12 +859,5 @@ public class ErrorMessages_sk extends ListResourceBundle { "FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present."} }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java index 66ee5fb53b3..93edfa9cae2 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java @@ -90,7 +90,13 @@ public class ErrorMessages_sv extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "Fler \u00E4n en formatmall har definierats i samma fil."}, @@ -964,12 +970,5 @@ public class ErrorMessages_sv extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java index 6896db34888..93889c37085 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java @@ -90,7 +90,13 @@ public class ErrorMessages_zh_CN extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "\u540C\u4E00\u6587\u4EF6\u4E2D\u5B9A\u4E49\u4E86\u591A\u4E2A\u6837\u5F0F\u8868\u3002"}, @@ -964,12 +970,5 @@ public class ErrorMessages_zh_CN extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java index 59c0b335f12..d99e7ec2a2b 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java @@ -90,7 +90,13 @@ public class ErrorMessages_zh_TW extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { {ErrorMsg.MULTIPLE_STYLESHEET_ERR, "\u76F8\u540C\u6A94\u6848\u4E2D\u5B9A\u7FA9\u4E86\u8D85\u904E\u4E00\u500B\u6A23\u5F0F\u8868\u3002"}, @@ -964,12 +970,5 @@ public class ErrorMessages_zh_TW extends ListResourceBundle { }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java index 37b4176f3b1..e1fd9e38df3 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java @@ -81,7 +81,13 @@ public class ErrorMessages extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "Use of the extension element ''{0}'' is not allowed when the secure processing feature is set to true."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ca.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ca.java index 1f1c461680d..a2b2ba14caa 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ca.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ca.java @@ -79,7 +79,13 @@ public class ErrorMessages_ca extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -223,13 +229,6 @@ public class ErrorMessages_ca extends ListResourceBundle { "No s''ha pogut resoldre la refer\u00e8ncia d''URI ''{0}''."} }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_cs.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_cs.java index 497367b8689..88409e1a507 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_cs.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_cs.java @@ -79,7 +79,13 @@ public class ErrorMessages_cs extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -223,13 +229,6 @@ public class ErrorMessages_cs extends ListResourceBundle { "Nelze p\u0159elo\u017eit odkazy URI ''{0}''."} }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_de.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_de.java index 181b4e17af5..747ae526d4e 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_de.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_de.java @@ -81,7 +81,13 @@ public class ErrorMessages_de extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_de extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "Verwendung des Erweiterungselements \"{0}\" ist nicht zul\u00E4ssig, wenn das Feature f\u00FCr die sichere Verarbeitung auf \"true\" gesetzt ist."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_es.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_es.java index a5979582a1c..7810adaf78e 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_es.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_es.java @@ -81,7 +81,13 @@ public class ErrorMessages_es extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_es extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "El uso del elemento de extensi\u00F3n ''{0}'' no est\u00E1 permitido cuando la funci\u00F3n de procesamiento seguro se ha definido en true."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_fr.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_fr.java index 5319304f456..28089e97bb3 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_fr.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_fr.java @@ -81,7 +81,13 @@ public class ErrorMessages_fr extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_fr extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "L''utilisation de l''\u00E9l\u00E9ment d''extension ''{0}'' n''est pas autoris\u00E9e lorsque la fonctionnalit\u00E9 de traitement s\u00E9curis\u00E9 est d\u00E9finie sur True."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_it.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_it.java index da6622e48c4..3fa594b215e 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_it.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_it.java @@ -81,7 +81,13 @@ public class ErrorMessages_it extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_it extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "Non \u00E8 consentito utilizzare l''elemento di estensione ''{0}'' se la funzione di elaborazione sicura \u00E8 impostata su true."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ja.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ja.java index 54dc000aa39..ce4f1708f5e 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ja.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ja.java @@ -81,7 +81,13 @@ public class ErrorMessages_ja extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_ja extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "\u30BB\u30AD\u30E5\u30A2\u51E6\u7406\u6A5F\u80FD\u304Ctrue\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u3068\u304D\u3001\u62E1\u5F35\u8981\u7D20''{0}''\u306E\u4F7F\u7528\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\u3002"}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ko.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ko.java index 87b532349b3..6ede7dfdd8a 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ko.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ko.java @@ -81,7 +81,13 @@ public class ErrorMessages_ko extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_ko extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "\uBCF4\uC548 \uCC98\uB9AC \uAE30\uB2A5\uC774 true\uB85C \uC124\uC815\uB41C \uACBD\uC6B0 \uD655\uC7A5 \uC694\uC18C ''{0}''\uC744(\uB97C) \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_pt_BR.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_pt_BR.java index 0eb0cfad52f..6004632a832 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_pt_BR.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_pt_BR.java @@ -81,7 +81,13 @@ public class ErrorMessages_pt_BR extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_pt_BR extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "O uso do elemento da extens\u00E3o ''{0}'' n\u00E3o ser\u00E1 permitido quando o recurso de processamento seguro for definido como verdadeiro."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sk.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sk.java index cf23692df73..6ee58b7c614 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sk.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sk.java @@ -79,7 +79,13 @@ public class ErrorMessages_sk extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -223,13 +229,6 @@ public class ErrorMessages_sk extends ListResourceBundle { "Nebolo mo\u017en\u00e9 rozl\u00ed\u0161i\u0165 referenciu URI ''{0}''."} }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sv.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sv.java index 0e7b2fe1fa1..14f6797117a 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sv.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sv.java @@ -81,7 +81,13 @@ public class ErrorMessages_sv extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_sv extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "Anv\u00E4ndning av till\u00E4ggselementet ''{0}'' \u00E4r inte till\u00E5tet n\u00E4r s\u00E4ker bearbetning till\u00E4mpas."}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_CN.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_CN.java index 2900d55f057..c673f2b5234 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_CN.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_CN.java @@ -81,7 +81,13 @@ public class ErrorMessages_zh_CN extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_zh_CN extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "\u5F53\u5B89\u5168\u5904\u7406\u529F\u80FD\u8BBE\u7F6E\u4E3A\u201C\u771F\u201D\u65F6, \u4E0D\u5141\u8BB8\u4F7F\u7528\u6269\u5C55\u5143\u7D20 ''{0}''\u3002"}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_TW.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_TW.java index 8e591a223ee..50972c6cb2e 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_TW.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_TW.java @@ -81,7 +81,13 @@ public class ErrorMessages_zh_TW extends ListResourceBundle { */ // These message should be read from a locale-specific resource bundle - private static final Object[][] _contents = new Object[][] { + /** Get the lookup table for error messages. + * + * @return The message lookup table. + */ + public Object[][] getContents() + { + return new Object[][] { /* * Note to translators: the substitution text in the following message @@ -276,13 +282,6 @@ public class ErrorMessages_zh_TW extends ListResourceBundle { {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, "\u7576\u5B89\u5168\u8655\u7406\u529F\u80FD\u8A2D\u70BA\u771F\u6642\uFF0C\u4E0D\u5141\u8A31\u4F7F\u7528\u64F4\u5145\u5957\u4EF6\u5143\u7D20 ''{0}''\u3002"}, }; - /** Get the lookup table for error messages. - * - * @return The message lookup table. - */ - public Object[][] getContents() - { - return _contents; } } From a78344ba67d9972106b05d4e58212abcb62e2ccc Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Thu, 10 Oct 2013 20:12:08 -0400 Subject: [PATCH 047/152] 8008762: Type annotation on inner class in anonymous class show up as regular type annotations 8015257: type annotation with TYPE_USE and FIELD attributed differently if repeated 8013409: test failures for type annotations Fixes to address some problems in type annotations Reviewed-by: jfranck, jjg --- .../com/sun/tools/javac/code/Attribute.java | 35 +- .../sun/tools/javac/code/TypeAnnotations.java | 23 +- .../com/sun/tools/javac/comp/MemberEnter.java | 5 - .../classes/com/sun/tools/javac/jvm/Gen.java | 9 +- .../classfile/TestAnonInnerClasses.java | 439 ++++++++++++++++++ .../classfile/testanoninner.template | 108 +++++ .../failures/CantAnnotateStaticClass.java | 2 +- .../failures/CantAnnotateStaticClass.out | 11 +- .../newlocations/MultiCatch.java | 1 + .../referenceinfos/MultiCatch.java | 1 + 10 files changed, 616 insertions(+), 18 deletions(-) create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/classfile/testanoninner.template diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java index 990ea0d06e0..7f45ee6e57b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java @@ -64,6 +64,8 @@ public abstract class Attribute implements AnnotationValue { return false; } + public TypeAnnotationPosition getPosition() { return null; }; + /** The value for an annotation element of primitive type or String. */ public static class Constant extends Attribute { public final Object value; @@ -191,8 +193,13 @@ public abstract class Attribute implements AnnotationValue { } public Attribute member(Name member) { + Pair res = getElemPair(member); + return res == null ? null : res.snd; + } + + private Pair getElemPair(Name member) { for (Pair pair : values) - if (pair.fst.name == member) return pair.snd; + if (pair.fst.name == member) return pair; return null; } @@ -208,6 +215,16 @@ public abstract class Attribute implements AnnotationValue { return (DeclaredType) type; } + @Override + public TypeAnnotationPosition getPosition() { + if (values.size() != 0) { + Name valueName = values.head.fst.name.table.names.value; + Pair res = getElemPair(valueName); + return res == null ? null : res.snd.getPosition(); + } + return null; + } + public Map getElementValues() { Map valmap = new LinkedHashMap(); @@ -230,6 +247,14 @@ public abstract class Attribute implements AnnotationValue { this.position = position; } + @Override + public TypeAnnotationPosition getPosition() { + if (hasUnknownPosition()) { + position = super.getPosition(); + } + return position; + } + public boolean hasUnknownPosition() { return position == null || position.type == TargetType.UNKNOWN; } @@ -302,6 +327,14 @@ public abstract class Attribute implements AnnotationValue { public R accept(AnnotationValueVisitor v, P p) { return v.visitArray(getValue(), p); } + + @Override + public TypeAnnotationPosition getPosition() { + if (values.length != 0) + return values[0].getPosition(); + else + return null; + } } /** The value for an annotation element of an enum type. diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 677319f1db6..61f77ff0608 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -71,6 +71,7 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Names; +import com.sun.tools.javac.util.Options; /** * Contains operations specific to processing type annotations. @@ -94,6 +95,7 @@ public class TypeAnnotations { final Names names; final Symtab syms; final Annotate annotate; + private final boolean typeAnnoAsserts; protected TypeAnnotations(Context context) { context.put(typeAnnosKey, this); @@ -101,6 +103,8 @@ public class TypeAnnotations { log = Log.instance(context); syms = Symtab.instance(context); annotate = Annotate.instance(context); + Options options = Options.instance(context); + typeAnnoAsserts = options.isSet("TypeAnnotationAsserts"); } /** @@ -265,10 +269,6 @@ public class TypeAnnotations { */ private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym, TypeAnnotationPosition pos) { - /* - System.out.printf("separateAnnotationsKinds(typetree: %s, type: %s, symbol: %s, pos: %s%n", - typetree, type, sym, pos); - */ List annotations = sym.getRawAttributes(); ListBuffer declAnnos = new ListBuffer(); ListBuffer typeAnnos = new ListBuffer(); @@ -1023,10 +1023,12 @@ public class TypeAnnotations { @Override public void visitMethodDef(final JCMethodDecl tree) { if (tree.sym == null) { - // Something most be wrong, e.g. a class not found. - // Quietly ignore. (See test FailOver15.java) + if (typeAnnoAsserts) { + Assert.error("Visiting tree node before memberEnter"); + } else { return; } + } if (sigOnly) { if (!tree.mods.annotations.isEmpty()) { // Nothing to do for separateAnnotationsKinds if @@ -1129,6 +1131,9 @@ public class TypeAnnotations { // Nothing to do for separateAnnotationsKinds if // there are no annotations of either kind. } else if (tree.sym == null) { + if (typeAnnoAsserts) { + Assert.error("Visiting tree node before memberEnter"); + } // Something is wrong already. Quietly ignore. } else if (tree.sym.getKind() == ElementKind.PARAMETER) { // Parameters are handled in visitMethodDef or visitLambda. @@ -1282,9 +1287,9 @@ public class TypeAnnotations { private void findPosition(JCTree tree, JCTree frame, List annotations) { if (!annotations.isEmpty()) { /* - System.out.println("Finding pos for: " + annotations); - System.out.println(" tree: " + tree + " kind: " + tree.getKind()); - System.out.println(" frame: " + frame + " kind: " + frame.getKind()); + System.err.println("Finding pos for: " + annotations); + System.err.println(" tree: " + tree + " kind: " + tree.getKind()); + System.err.println(" frame: " + frame + " kind: " + frame.getKind()); */ TypeAnnotationPosition p = new TypeAnnotationPosition(); p.onLambda = currentLambda; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index d611fbac7e8..0c997914ed6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -643,9 +643,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (TreeInfo.isEnumInit(tree)) { attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); } else { - // Make sure type annotations are processed. - // But we don't have a symbol to attach them to yet - use null. - typeAnnotate(tree.vartype, env, null, tree.pos()); attr.attribType(tree.vartype, localEnv); if (tree.nameexpr != null) { attr.attribExpr(tree.nameexpr, localEnv); @@ -696,7 +693,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); typeAnnotate(tree.vartype, env, v, tree.pos()); - annotate.flush(); v.pos = tree.pos; } // where @@ -1084,7 +1080,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { // Do this here, where we have the symbol. for (JCTypeParameter tp : tree.typarams) typeAnnotate(tp, baseEnv, sym, tree.pos()); - annotate.flush(); // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index 7e727f23955..b48b727090f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -104,6 +104,8 @@ public class Gen extends JCTree.Visitor { */ private LVTRanges lvtRanges; + private final boolean typeAnnoAsserts; + protected Gen(Context context) { context.put(genKey, this); @@ -140,6 +142,7 @@ public class Gen extends JCTree.Visitor { debugCode = options.isSet("debugcode"); allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic"); pool = new Pool(types); + typeAnnoAsserts = options.isSet("TypeAnnotationAsserts"); generateIproxies = target.requiresIproxy() || @@ -562,9 +565,13 @@ public class Gen extends JCTree.Visitor { ListBuffer fieldTAs = new ListBuffer(); ListBuffer nonfieldTAs = new ListBuffer(); for (TypeCompound ta : tas) { - if (ta.position.type == TargetType.FIELD) { + if (ta.getPosition().type == TargetType.FIELD) { fieldTAs.add(ta); } else { + if (typeAnnoAsserts) { + Assert.error("Type annotation does not have a valid positior"); + } + nonfieldTAs.add(ta); } } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java new file mode 100644 index 00000000000..0ce59a87b0c --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8005085 8008762 8008751 8013065 8015323 8015257 + * @summary Type annotations on anonymous and inner class. + * Six TYPE_USE annotations are repeated(or not); Four combinations create + * four test files, and each results in the test class and 2 anonymous classes. + * Each element of these three classes is checked for expected number of the + * four annotation Attributes. Expected annotation counts depend on type of + * annotation place on type of element (a FIELD&TYPE_USE element on a field + * results in 2). Elements with no annotations expect 0. + * Source template is read in from testanoninner.template + * + */ +import java.lang.annotation.*; +import java.io.*; +import java.util.List; +import java.util.LinkedList; +import com.sun.tools.classfile.*; +import java.nio.file.Files; +import java.nio.charset.*; +import java.io.File; +import java.io.IOException; + + +import java.lang.annotation.*; +import static java.lang.annotation.RetentionPolicy.*; +import static java.lang.annotation.ElementType.*; + +/* + * A source template is read in and testname and annotations are inserted + * via replace(). + */ +public class TestAnonInnerClasses extends ClassfileTestHelper { + // tally errors and test cases + int errors = 0; + int checks = 0; + //Note expected test count in case of skips due to bugs. + int tc = 0, xtc = 180; // 45 x 4 variations of repeated annotations. + File testSrc = new File(System.getProperty("test.src")); + + String[] AnnoAttributes = { + Attribute.RuntimeVisibleTypeAnnotations, + Attribute.RuntimeInvisibleTypeAnnotations, + Attribute.RuntimeVisibleAnnotations, + Attribute.RuntimeInvisibleAnnotations + }; + + // template for source files + String srcTemplate = "testanoninner.template"; + + // Four test files generated based on combinations of repeating annotations. + Boolean As= false, Bs=true, Cs=false, Ds=false, TAs=false,TBs=false; + Boolean[][] bRepeat = new Boolean[][]{ + /* no repeats */ {false, false, false, false, false, false}, + /* repeat A,C,TA */ {true, false, true, false, true, false}, + /* repeat B,D,TB */ {false, true, false, true, false, true}, + /* repeat all */ {true, true, true, true, true, true} + }; + // Save descriptions of failed test case; does not terminate upon a failure. + List failed = new LinkedList<>(); + + public static void main(String[] args) throws Exception { + new TestAnonInnerClasses().run(); + } + + // Check annotation counts and make reports sufficiently descriptive to + // easily diagnose. + void check(String testcase, int vtaX, int itaX, int vaX, int iaX, + int vtaA, int itaA, int vaA, int iaA) { + + String descr = " checking " + testcase+" _TYPE_, expected: " + + vtaX + ", " + itaX + ", " + vaX + ", " + iaX + "; actual: " + + vtaA + ", " + itaA + ", " + vaA + ", " + iaA; + String description; + description=descr.replace("_TYPE_","RuntimeVisibleTypeAnnotations"); + if (vtaX != vtaA) { + errors++; + failed.add(++checks + " " + testcase + ": (vtaX) " + vtaX + + " != " + vtaA + " (vtaA)"); + println(checks + " FAIL: " + description); + } else { + println(++checks + " PASS: " + description); + } + description=descr.replace("_TYPE_","RuntimeInvisibleTypeAnnotations"); + if (itaX != itaA) { + errors++; + failed.add(++checks + " " + testcase + ": (itaX) " + itaX + " != " + + itaA + " (itaA)"); + println(checks + " FAIL: " + description); + } else { + println(++checks + " PASS: " + description); + } + description=descr.replace("_TYPE_","RuntimeVisibleAnnotations"); + if (vaX != vaA) { + errors++; + failed.add(++checks + " " + testcase + ": (vaX) " + vaX + " != " + + vaA + " (vaA)"); + println(checks + " FAIL: " + description); + } else { + println(++checks + " PASS: " + description); + } + description=descr.replace("_TYPE_","RuntimeInvisibleAnnotations"); + if (iaX != iaA) { + errors++; + failed.add(++checks + " " + testcase + ": (iaX) " + iaX + " != " + + iaA + " (iaA)"); + println(checks + " FAIL: " + description); + } else { + println(++checks + " PASS: " + description); + } + println(""); + } + + // Print failed cases (if any) and throw exception for fail. + void report() { + if (errors!=0) { + System.err.println("Failed tests: " + errors + + "\nfailed test cases:\n"); + for (String t: failed) System.err.println(" " + t); + throw new RuntimeException("FAIL: There were test failures."); + } else + System.out.println("PASSED all tests."); + } + + void test(String ttype, ClassFile cf, Method m, Field f, boolean visible) { + int vtaActual = 0, + itaActual = 0, + vaActual = 0, + iaActual = 0, + vtaExp = 0, + itaExp = 0, + vaExp = 0, + iaExp = 0, + index = 0, + index2 = 0; + String memberName = null, + testcase = "undefined", + testClassName = null; + Attribute attr = null, + cattr = null; + Code_attribute CAttr = null; + // Get counts of 4 annotation Attributes on element being checked. + for (String AnnoType : AnnoAttributes) { + try { + switch (ttype) { + case "METHOD": + index = m.attributes.getIndex(cf.constant_pool, + AnnoType); + memberName = m.getName(cf.constant_pool); + if (index != -1) + attr = m.attributes.get(index); + //fetch index annotations from code attribute. + index2 = m.attributes.getIndex(cf.constant_pool, + Attribute.Code); + if (index2 != -1) { + cattr = m.attributes.get(index2); + assert cattr instanceof Code_attribute; + CAttr = (Code_attribute)cattr; + index2 = CAttr.attributes.getIndex(cf.constant_pool, + AnnoType); + if (index2 != -1) + cattr = CAttr.attributes.get(index2); + } + break; + case "FIELD": + index = f.attributes.getIndex(cf.constant_pool, + AnnoType); + memberName = f.getName(cf.constant_pool); + if (index != -1) + attr = f.attributes.get(index); + //fetch index annotations from code attribute. + index2 = cf.attributes.getIndex(cf.constant_pool, + Attribute.Code); + if (index2!= -1) { + cattr = cf.attributes.get(index2); + assert cattr instanceof Code_attribute; + CAttr = (Code_attribute)cattr; + index2 = CAttr.attributes.getIndex(cf.constant_pool, + AnnoType); + if (index2!= -1) + cattr = CAttr.attributes.get(index2); + } + break; + + default: + memberName = cf.getName(); + index = cf.attributes.getIndex(cf.constant_pool, + AnnoType); + if (index!= -1) attr = cf.attributes.get(index); + break; + } + } + catch (ConstantPoolException cpe) { cpe.printStackTrace(); } + try { + testClassName=cf.getName(); + testcase = ttype + ": " + testClassName + ": " + + memberName + ", "; + } + catch (ConstantPoolException cpe) { cpe.printStackTrace(); } + if (index != -1) { + switch (AnnoType) { + case Attribute.RuntimeVisibleTypeAnnotations: + //count RuntimeVisibleTypeAnnotations + RuntimeVisibleTypeAnnotations_attribute RVTAa = + (RuntimeVisibleTypeAnnotations_attribute)attr; + vtaActual += RVTAa.annotations.length; + break; + case Attribute.RuntimeVisibleAnnotations: + //count RuntimeVisibleAnnotations + RuntimeVisibleAnnotations_attribute RVAa = + (RuntimeVisibleAnnotations_attribute)attr; + vaActual += RVAa.annotations.length; + break; + case Attribute.RuntimeInvisibleTypeAnnotations: + //count RuntimeInvisibleTypeAnnotations + RuntimeInvisibleTypeAnnotations_attribute RITAa = + (RuntimeInvisibleTypeAnnotations_attribute)attr; + itaActual += RITAa.annotations.length; + break; + case Attribute.RuntimeInvisibleAnnotations: + //count RuntimeInvisibleAnnotations + RuntimeInvisibleAnnotations_attribute RIAa = + (RuntimeInvisibleAnnotations_attribute)attr; + iaActual += RIAa.annotations.length; + break; + } + } + // annotations from code attribute. + if (index2 != -1) { + switch (AnnoType) { + case Attribute.RuntimeVisibleTypeAnnotations: + //count RuntimeVisibleTypeAnnotations + RuntimeVisibleTypeAnnotations_attribute RVTAa = + (RuntimeVisibleTypeAnnotations_attribute)cattr; + vtaActual += RVTAa.annotations.length; + break; + case Attribute.RuntimeVisibleAnnotations: + //count RuntimeVisibleAnnotations + RuntimeVisibleAnnotations_attribute RVAa = + (RuntimeVisibleAnnotations_attribute)cattr; + vaActual += RVAa.annotations.length; + break; + case Attribute.RuntimeInvisibleTypeAnnotations: + //count RuntimeInvisibleTypeAnnotations + RuntimeInvisibleTypeAnnotations_attribute RITAa = + (RuntimeInvisibleTypeAnnotations_attribute)cattr; + itaActual += RITAa.annotations.length; + break; + case Attribute.RuntimeInvisibleAnnotations: + //count RuntimeInvisibleAnnotations + RuntimeInvisibleAnnotations_attribute RIAa = + (RuntimeInvisibleAnnotations_attribute)cattr; + iaActual += RIAa.annotations.length; + break; + } + } + } + + switch (memberName) { + //METHODs + case "test" : vtaExp=4; itaExp=4; vaExp=0; iaExp=0; tc++; break; + case "mtest": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "m1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "m2": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "m3": vtaExp=10; itaExp=10; vaExp=1; iaExp=1; tc++; break; + case "tm": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + //inner class + case "i_m1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "i_m2": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "i_um": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + //local class + case "l_m1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "l_m2": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "l_um": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + //anon class + case "mm_m1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "mm_m2": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "mm_m3": vtaExp=10; itaExp=10;vaExp=1; iaExp=1; tc++; break; + case "mm_tm": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + //InnerAnon class + case "ia_m1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "ia_m2": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "ia_um": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + //FIELDs + case "data": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "odata1": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "pdata1": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "tdata": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "sa1": vtaExp = 6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + //inner class + case "i_odata1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "i_pdata1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "i_udata": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "i_sa1": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + case "i_tdata": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + //local class + case "l_odata1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "l_pdata1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "l_udata": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "l_sa1": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + case "l_tdata": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + //anon class + case "mm_odata1": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "mm_pdata1": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "mm_sa1": vtaExp = 6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + case "mm_tdata": vtaExp = 2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + // InnerAnon class + case "ia_odata1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "ia_pdata1": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "ia_udata": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "ia_sa1": vtaExp=6; itaExp=6; vaExp=1; iaExp=1; tc++; break; + case "ia_tdata": vtaExp=2; itaExp=2; vaExp=1; iaExp=1; tc++; break; + case "IA": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + case "IN": vtaExp=4; itaExp=4; vaExp=1; iaExp=1; tc++; break; + // default cases are , this$0, this$1, mmtest, atest + default: vtaExp = 0; itaExp=0; vaExp=0; iaExp=0; break; + } + check(testcase,vtaExp, itaExp, vaExp, iaExp, + vtaActual,itaActual,vaActual,iaActual); + } + + public void run() { + ClassFile cf = null; + InputStream in = null; + int testcount = 1; + File testFile = null; + // Generate source, check methods and fields for each combination. + for (Boolean[] bCombo : bRepeat) { + As=bCombo[0]; Bs=bCombo[1]; Cs=bCombo[2]; + Ds=bCombo[3]; TAs=bCombo[4]; TBs=bCombo[5]; + String testname = "Test" + testcount++; + println("Combinations: " + As + ", " + Bs + ", " + Cs + ", " + Ds + + ", " + TAs + ", " + TBs + + "; see " + testname + ".java"); + String[] classes = {testname + ".class", + testname + "$Inner.class", + testname + "$1Local1.class", + testname + "$1.class", + testname + "$1$1.class", + testname + "$1$InnerAnon.class" + }; + // Create test source, create and compile File. + String sourceString = getSource(srcTemplate, testname, + As, Bs, Cs, Ds, TAs, TBs); + System.out.println(sourceString); + try { + testFile = writeTestFile(testname+".java", sourceString); + } + catch (IOException ioe) { ioe.printStackTrace(); } + // Compile test source and read classfile. + File classFile = null; + try { + classFile = compile(testFile); + } + catch (Error err) { + System.err.println("FAILED compile. Source:\n" + sourceString); + throw err; + } + String testloc = classFile.getAbsolutePath().substring( + 0,classFile.getAbsolutePath().indexOf(classFile.getPath())); + for (String clazz : classes) { + try { + cf = ClassFile.read(new File(testloc+clazz)); + } + catch (Exception e) { e.printStackTrace(); } + // Test for all methods and fields + for (Method m: cf.methods) { + test("METHOD", cf, m, null, true); + } + for (Field f: cf.fields) { + test("FIELD", cf, null, f, true); + } + } + } + report(); + if (tc!=xtc) System.out.println("Test Count: " + tc + " != " + + "expected: " + xtc); + } + + + String getSrcTemplate(String sTemplate) { + List tmpl = null; + String sTmpl = ""; + try { + tmpl = Files.readAllLines(new File(testSrc,sTemplate).toPath(), + Charset.defaultCharset()); + } + catch (IOException ioe) { + String error = "FAILED: Test failed to read template" + sTemplate; + ioe.printStackTrace(); + throw new RuntimeException(error); + } + for (String l : tmpl) + sTmpl=sTmpl.concat(l).concat("\n"); + return sTmpl; + } + + // test class template + String getSource(String templateName, String testname, + Boolean Arepeats, Boolean Brepeats, + Boolean Crepeats, Boolean Drepeats, + Boolean TArepeats, Boolean TBrepeats) { + String As = Arepeats ? "@A @A":"@A", + Bs = Brepeats ? "@B @B":"@B", + Cs = Crepeats ? "@C @C":"@C", + Ds = Drepeats ? "@D @D":"@D", + TAs = TArepeats ? "@TA @TA":"@TA", + TBs = TBrepeats ? "@TB @TB":"@TB"; + + // split up replace() lines for readability + String testsource = getSrcTemplate(templateName).replace("testname",testname); + testsource = testsource.replace("_As",As).replace("_Bs",Bs).replace("_Cs",Cs); + testsource = testsource.replace("_Ds",Ds).replace("_TAs",TAs).replace("_TBs",TBs); + return testsource; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/testanoninner.template b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/testanoninner.template new file mode 100644 index 00000000000..ee384bf8662 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/testanoninner.template @@ -0,0 +1,108 @@ +import java.lang.annotation.*; +import static java.lang.annotation.RetentionPolicy.*; +import static java.lang.annotation.ElementType.*; +import java.util.List; + +class testname { // TestN.class + _As _Bs _Cs _Ds String data = "test"; + _As _Bs _Cs _Ds Object mtest( _As _Bs _Cs _Ds testname t){ return null; } + Object mmtest( testname t){ return null; } + + class Inner { // TestN$1$Inner.class + _As _Bs _Cs _Ds String i_odata1 = "test"; + _As _Bs _Cs _Ds int i_pdata1 = 0; + _As _Bs _Cs _Ds U i_udata = null; +//8015257 + _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds [] _As _Bs _Cs _Ds [] i_sa1 = null; + _As _Bs _Cs _Ds T i_tdata = null; + _As _Bs _Cs _Ds String i_m1(){ return null; }; + _As _Bs _Cs _Ds int i_m2( _As _Bs _Cs _Ds Object o){return 0;} + _As _Bs _Cs _Ds + <_TAs _TBs _Cs _Ds U> Object i_um( _As _Bs _Cs _Ds U u) { return null; } + } +//8015323 + _As _Bs _Cs _Ds Inner< _As _Bs _Cs _Ds String> IN = new Inner< String>(); + + public void test() { + + class Local1 { // TestN$Local1.class + _As _Bs _Cs _Ds String l_odata1 = "test"; + _As _Bs _Cs _Ds int l_pdata1 = 0; + _As _Bs _Cs _Ds U l_udata = null; +//8015257 + _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] l_sa1 = null; + _TAs _TBs _Cs _Ds T l_tdata = null; + _As _Bs _Cs _Ds String l_m1(){ return null; }; + _As _Bs _Cs _Ds int l_m2(_As _Bs _Cs _Ds Object o){return 0;} + _As _Bs _Cs _Ds + <_TAs _TBs _Cs _Ds U> Object l_um(_As _Bs _Cs _Ds U u) { return null; } + } + // The below, as a local variable, will show up on test() + _As _Bs _Cs _Ds Local1<_As _Bs _Cs _Ds String> LC = new Local1(); + + mtest( new testname() { // TestN$1 + class InnerAnon { // TestN$1$InnerAnon.class + _As _Bs _Cs _Ds String ia_odata1 = "test"; + _As _Bs _Cs _Ds int ia_pdata1 = 0; + _As _Bs _Cs _Ds U ia_udata = null; +//8015257 + _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] ia_sa1 = null; + _TAs _TBs _Cs _Ds T ia_tdata = null; + _As _Bs _Cs _Ds String ia_m1(){ return null; }; + _As _Bs _Cs _Ds int ia_m2(_As _Bs _Cs _Ds Object o){return 0;} + _As _Bs _Cs _Ds + <_TAs _TBs _Cs _Ds U> Object ia_um(_As _Bs _Cs _Ds U u) { return null; } + } +//8015257 + _As _Bs _Cs _Ds InnerAnon<_As _Bs _Cs _Ds String> IA = new InnerAnon< String>(); + + _As _Bs _Cs _Ds String odata1 = "test"; + _As _Bs _Cs _Ds int pdata1 = 0; +//8015257 + _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] sa1 = null; + _As _Bs _Cs _Ds T tdata = null; + + _As _Bs _Cs _Ds String m1(){ return null; }; + _As _Bs _Cs _Ds int m2(_As _Bs _Cs _Ds Object o){return 0;} + + _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds [] _As _Bs _Cs _Ds [] + m3(String _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] sa){ return null; } + + _As _Bs _Cs _Ds + <_TAs _TBs _Cs _Ds T> Object tm(_As _Bs _Cs _Ds T t) { return null; } + + public void atest( testname t){ + t.mmtest( new testname() { // TestN$1$1.class + _As _Bs _Cs _Ds String mm_odata1 = "test"; + _As _Bs _Cs _Ds int mm_pdata1 = 0; +//8015257 + _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] mm_sa1 = null; + _TAs _TBs _Cs _Ds T mm_tdata = null; + + _As _Bs _Cs _Ds String mm_m1(){ return null; }; + _As _Bs _Cs _Ds int mm_m2(_As _Bs _Cs _Ds Object o){return 0;} + + _As _Bs _Cs _Ds String _As _Bs _Cs _Ds [] _As _Bs _Cs _Ds [] + mm_m3(String _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] sa){ return null; } + + _As _Bs _Cs _Ds + <_TAs _TBs _Cs _Ds T> Object mm_tm(_As _Bs _Cs _Ds T t) { return null; } + }); + } + }); + } +} +@Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @Repeatable( AC.class ) @interface A { } +@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @Repeatable( BC.class ) @interface B { } +@Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface AC { A[] value(); } +@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @interface BC { B[] value(); } + +@Retention(CLASS) @Target({TYPE_USE,FIELD}) @Repeatable( CC.class ) @interface C { } +@Retention(CLASS) @Target({TYPE_USE,METHOD}) @Repeatable( DC.class ) @interface D { } +@Retention(CLASS) @Target({TYPE_USE,FIELD}) @interface CC { C[] value(); } +@Retention(CLASS) @Target({TYPE_USE,METHOD}) @interface DC { D[] value(); } + +@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,FIELD}) @Repeatable( TAC.class ) @interface TA { } +@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,METHOD}) @Repeatable( TBC.class ) @interface TB { } +@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,FIELD}) @interface TAC { TA[] value(); } +@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,METHOD}) @interface TBC { TB[] value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java index 70bc051f07b..98a38e220da 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 8006733 8006775 - * @ignore 8013409: test failures for type annotations + * @summary A static outer class cannot be annotated. * @author Werner Dietl * @compile/fail/ref=CantAnnotateStaticClass.out -XDrawDiagnostics CantAnnotateStaticClass.java diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out index 2995a4d0e74..3223539ca24 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out @@ -1 +1,10 @@ -dummy \ No newline at end of file +CantAnnotateStaticClass.java:22:20: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:23:13: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:24:29: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:26:29: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:29:26: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:30:9: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:31:35: compiler.err.cant.annotate.static.class +- compiler.note.unchecked.filename: CantAnnotateStaticClass.java +- compiler.note.unchecked.recompile +7 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java index 8a1545d2f34..59b02d7b105 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java @@ -25,6 +25,7 @@ import java.lang.annotation.*; /* * @test + * @ignore 8008762 Type annotations failures * @bug 8006775 * @summary new type annotation location: multicatch * @author Werner Dietl diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java index 7c16a0d7b66..aaa2faac469 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java @@ -25,6 +25,7 @@ import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; /* * @test + * @ignore 8008762 Type annotation failures * @bug 8006732 8006775 * @summary Test population of reference info for multicatch exception parameters * @author Werner Dietl From a29d963e53ec89d7e66496653b1cfc5c550e6fbb Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 10 Oct 2013 17:13:32 -0700 Subject: [PATCH 048/152] 8026294: 8025633 breaks langtools/test/com/sun/javadoc/testRepeatedAnnotations/TestRepeatedAnnotations.java Reviewed-by: darcy --- .../TestRepeatedAnnotations.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/TestRepeatedAnnotations.java b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/TestRepeatedAnnotations.java index 709b2ef2d32..fd4913486e2 100644 --- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/TestRepeatedAnnotations.java +++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/TestRepeatedAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. 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 @@ -56,7 +56,7 @@ public class TestRepeatedAnnotations extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "C.html", "@RegContainerDoc" + - "(value={" + + "(value={" + "@RegContaineeNotDoc," + "@ContainerSynthDoc(" + - "value=" + + "value=" + "@ContaineeSynthDoc)"}, {BUG_ID + FS + "pkg" + FS + "C.html", @@ -82,37 +82,37 @@ public class TestRepeatedAnnotations extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "D.html", "@RegDoc" + - "(x=1)"}, + "(x=1)"}, {BUG_ID + FS + "pkg" + FS + "D.html", "@RegArryDoc" + - "(y=1)"}, + "(y=1)"}, {BUG_ID + FS + "pkg" + FS + "D.html", "@RegArryDoc" + - "(y={1,2})"}, + "(y={1,2})"}, {BUG_ID + FS + "pkg" + FS + "D.html", "@NonSynthDocContainer" + - "(value=" + + "(value=" + "@RegArryDoc)"}, {BUG_ID + FS + "pkg1" + FS + "C.html", "@RegContainerValDoc" + - "(value={" + + "(value={" + "@RegContaineeNotDoc," + "@RegContaineeNotDoc}," + - "y=3)"}, + "y=3)"}, {BUG_ID + FS + "pkg1" + FS + "C.html", "@ContainerValDoc" + - "(value={" + + "(value={" + "@ContaineeNotDoc," + "@ContaineeNotDoc}," + - "x=1)"} + "x=1)"} }; private static final String[][] NEGATED_TEST = { @@ -124,7 +124,7 @@ public class TestRepeatedAnnotations extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "C.html", "@RegContainerNotDoc" + - "(value={" + + "(value={" + "@RegContaineeNotDoc," + "@RegContainerValNotDoc" + - "(value={" + + "(value={" + "@RegContaineeDoc," + "@RegContaineeDoc}," + - "y=4)"}, + "y=4)"}, {BUG_ID + FS + "pkg1" + FS + "C.html", "@ContainerValNotDoc" + - "(value={" + + "(value={" + "@ContaineeNotDoc," + "@ContaineeNotDoc}," + - "x=2)"}, + "x=2)"}, {BUG_ID + FS + "pkg1" + FS + "C.html", "@ContainerSynthNotDoc(" + - "value=" + + "value=" + "@ContaineeSynthDoc)"} }; From 36d36b2eda989b0eea8361e8324ff0c3f59f4b04 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 11 Oct 2013 06:50:06 +0200 Subject: [PATCH 049/152] 8026263: [NASHORN] Test test/script/basic/JDK-8025488.js fails in nightly builds Reviewed-by: jlaskey --- nashorn/test/script/basic/JDK-8025488.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nashorn/test/script/basic/JDK-8025488.js b/nashorn/test/script/basic/JDK-8025488.js index a3697f411ba..8229b9facdb 100644 --- a/nashorn/test/script/basic/JDK-8025488.js +++ b/nashorn/test/script/basic/JDK-8025488.js @@ -40,4 +40,4 @@ MyError.prototype.toString = function() { } var e = new MyError(); -print(e.stack); +print(e.stack.replace(/\\/g, '/')); From a8e63b82f1ebaa5ac1308d5893fa911e67fd3309 Mon Sep 17 00:00:00 2001 From: Robert Field Date: Thu, 10 Oct 2013 23:26:56 -0700 Subject: [PATCH 050/152] 8012557: Implement lambda methods on interfaces as private 8016320: Method reference in subinterface of type I.super::foo produces exception at runtime Now that the VM supports interface instance private methods, lambda methods and lambda bridges are always private. Access is now through invokespecial. Reviewed-by: vromero, jlahoda --- .../sun/tools/javac/comp/LambdaToMethod.java | 23 +++-- .../classes/com/sun/tools/javac/jvm/Pool.java | 3 + .../test/tools/javac/lambda/8012557/A.java | 30 +++++++ .../test/tools/javac/lambda/8012557/B.java | 30 +++++++ .../test/tools/javac/lambda/8012557/C.java | 30 +++++++ .../javac/lambda/8012557/PrivateLambdas.java | 88 +++++++++++++++++++ .../test/tools/javac/lambda/8012557/SAM.java | 26 ++++++ .../lambda/8016320/IllegalBridgeModifier.java | 55 ++++++++++++ 8 files changed, 273 insertions(+), 12 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/8012557/A.java create mode 100644 langtools/test/tools/javac/lambda/8012557/B.java create mode 100644 langtools/test/tools/javac/lambda/8012557/C.java create mode 100644 langtools/test/tools/javac/lambda/8012557/PrivateLambdas.java create mode 100644 langtools/test/tools/javac/lambda/8012557/SAM.java create mode 100644 langtools/test/tools/javac/lambda/8016320/IllegalBridgeModifier.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index eb15ef65c11..e56aa535706 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -128,10 +128,9 @@ public class LambdaToMethod extends TreeTranslator { private KlassInfo(Symbol kSym) { appendedMethodList = new ListBuffer<>(); deserializeCases = new HashMap>(); - long flags = PRIVATE | STATIC | SYNTHETIC; MethodType type = new MethodType(List.of(syms.serializedLambdaType), syms.objectType, List.nil(), syms.methodClass); - deserMethodSym = makeSyntheticMethod(flags, names.deserializeLambda, type, kSym); + deserMethodSym = makePrivateSyntheticMethod(STATIC, names.deserializeLambda, type, kSym); deserParamSym = new VarSymbol(FINAL, names.fromString("lambda"), syms.serializedLambdaType, deserMethodSym); } @@ -671,8 +670,8 @@ public class LambdaToMethod extends TreeTranslator { /** * Create new synthetic method with given flags, name, type, owner */ - private MethodSymbol makeSyntheticMethod(long flags, Name name, Type type, Symbol owner) { - return new MethodSymbol(flags | SYNTHETIC, name, type, owner); + private MethodSymbol makePrivateSyntheticMethod(long flags, Name name, Type type, Symbol owner) { + return new MethodSymbol(flags | SYNTHETIC | PRIVATE, name, type, owner); } /** @@ -1067,12 +1066,12 @@ public class LambdaToMethod extends TreeTranslator { } else { if (refSym.isStatic()) { return ClassFile.REF_invokeStatic; + } else if ((refSym.flags() & PRIVATE) != 0) { + return ClassFile.REF_invokeSpecial; } else if (refSym.enclClass().isInterface()) { return ClassFile.REF_invokeInterface; } else { - return (refSym.flags() & PRIVATE) != 0 ? - ClassFile.REF_invokeSpecial : - ClassFile.REF_invokeVirtual; + return ClassFile.REF_invokeVirtual; } } } @@ -1480,7 +1479,7 @@ public class LambdaToMethod extends TreeTranslator { //static clinits are generated in Gen - so we need to fake them Symbol clinit = clinits.get(csym); if (clinit == null) { - clinit = makeSyntheticMethod(STATIC, + clinit = makePrivateSyntheticMethod(STATIC, names.clinit, new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass), csym); @@ -1729,7 +1728,7 @@ public class LambdaToMethod extends TreeTranslator { self = ((JCVariableDecl)frame.tree).sym; } Name name = isSerializable() ? serializedLambdaName(owner) : lambdaName(); - this.translatedSym = makeSyntheticMethod(0, name, null, owner.enclClass()); + this.translatedSym = makePrivateSyntheticMethod(0, name, null, owner.enclClass()); if (dumpLambdaToMethodStats) { log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym); } @@ -1845,9 +1844,9 @@ public class LambdaToMethod extends TreeTranslator { // If instance access isn't needed, make it static. // Interface instance methods must be default methods. - // Awaiting VM channges, default methods are public + // Lambda methods are private synthetic. translatedSym.flags_field = SYNTHETIC | - ((inInterface && thisReferenced)? PUBLIC : PRIVATE) | + PRIVATE | (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); //compute synthetic params @@ -1890,7 +1889,7 @@ public class LambdaToMethod extends TreeTranslator { super(tree); this.isSuper = tree.hasKind(ReferenceKind.SUPER); this.bridgeSym = needsBridge() - ? makeSyntheticMethod(isSuper ? 0 : STATIC, + ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC, lambdaName().append(names.fromString("$bridge")), null, owner.enclClass()) : null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java index 1437135ae56..4389d08bd3e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java @@ -296,7 +296,10 @@ public class Pool { interfaceOwner = true; staticOk = true; case ClassFile.REF_invokeVirtual: + expectedKind = Kinds.MTH; + break; case ClassFile.REF_invokeSpecial: + interfaceOwner = true; expectedKind = Kinds.MTH; break; } diff --git a/langtools/test/tools/javac/lambda/8012557/A.java b/langtools/test/tools/javac/lambda/8012557/A.java new file mode 100644 index 00000000000..4dd16a86667 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8012557/A.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +interface A { + default String u() { return "A"; } + default String name() { + SAM s = ()->u()+"A"; + return s.m(); + } +} diff --git a/langtools/test/tools/javac/lambda/8012557/B.java b/langtools/test/tools/javac/lambda/8012557/B.java new file mode 100644 index 00000000000..b195af14336 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8012557/B.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +interface B { + default String u() { return "B"; } + default String name() { + SAM s = ()->u()+"B"; + return s.m(); + } +} diff --git a/langtools/test/tools/javac/lambda/8012557/C.java b/langtools/test/tools/javac/lambda/8012557/C.java new file mode 100644 index 00000000000..a6839e96bcf --- /dev/null +++ b/langtools/test/tools/javac/lambda/8012557/C.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +interface C { + default String u() { return "C"; } + default String name() { + SAM s = ()->u()+"C"; + return s.m(); + } +} diff --git a/langtools/test/tools/javac/lambda/8012557/PrivateLambdas.java b/langtools/test/tools/javac/lambda/8012557/PrivateLambdas.java new file mode 100644 index 00000000000..d77dda6adf8 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8012557/PrivateLambdas.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8012557 + * @summary Check that 8012557 is fixed, that interface lambda + * methods are private + * @author Robert Field + * @compile SAM.java + * @compile A.java + * @compile B.java + * @compile C.java + * @run main PrivateLambdas + * + * Unless the lambda methods are private, this will fail with: + * AbstractMethodError: + * Conflicting default methods: A.lambda$0 B.lambda$0 C.lambda$0 + */ + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +interface X extends A, B, C { + default String u() { return " "; } + default String name() { + return A.super.name() + B.super.name() + C.super.name(); + } +} + +public class PrivateLambdas implements X { + public static void main(String[] args) throws Exception { + + // Check that all the lambda methods are private instance synthetic + for (Class k : new Class[] { A.class, B.class, C.class }) { + Method[] methods = k.getDeclaredMethods(); + int lambdaCount = 0; + for(Method m : methods) { + if (m.getName().startsWith("lambda$")) { + ++lambdaCount; + int mod = m.getModifiers(); + if ((mod & Modifier.PRIVATE) == 0) { + throw new Exception("Expected " + m + " to be private"); + } + if (!m.isSynthetic()) { + throw new Exception("Expected " + m + " to be synthetic"); + } + if ((mod & Modifier.STATIC) != 0) { + throw new Exception("Expected " + m + " to be instance method"); + } + } + } + if (lambdaCount == 0) { + throw new Exception("Expected at least one lambda method"); + } + } + + /* + * Unless the lambda methods are private, this will fail with: + * AbstractMethodError: + * Conflicting default methods: A.lambda$0 B.lambda$0 C.lambda$0 + */ + X x = new PrivateLambdas(); + if (!x.name().equals(" A B C")) { + throw new Exception("Expected ' A B C' got: " + x.name()); + } + } +} diff --git a/langtools/test/tools/javac/lambda/8012557/SAM.java b/langtools/test/tools/javac/lambda/8012557/SAM.java new file mode 100644 index 00000000000..25bbae929f4 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8012557/SAM.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +interface SAM { + String m(); +} diff --git a/langtools/test/tools/javac/lambda/8016320/IllegalBridgeModifier.java b/langtools/test/tools/javac/lambda/8016320/IllegalBridgeModifier.java new file mode 100644 index 00000000000..3578bbcd780 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016320/IllegalBridgeModifier.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8016320 + * @summary Check that 8016320 is fixed, + * that bridges have valid modifier bits + * @author Robert Field + * @run main IllegalBridgeModifier + */ + +interface SAM { + int m(); +} + +interface SuperI { + public default int foo() { return 1234; } +} + +interface I extends SuperI { +} + +interface T extends I { + public default SAM boo() { return I.super::foo; } +} + +public class IllegalBridgeModifier { + public static void main(String argv[])throws Exception { + T t = new T(){}; + if (t.boo().m() != 1234) { + throw new Exception("Failed test"); + } + } +} From 02625b48e3a3a1c1fc7b577223bfb99142949fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 11 Oct 2013 10:56:08 +0200 Subject: [PATCH 051/152] 8026292: Megamorphic setter fails with boolean value Reviewed-by: jlaskey, sundar --- .../internal/codegen/MethodEmitter.java | 2 +- nashorn/test/script/basic/JDK-8026292.js | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8026292.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java index 7b452421bcf..9b6d12aae88 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java @@ -1793,7 +1793,7 @@ public class MethodEmitter implements Emitter { debug("dynamic_set", name, peekType()); Type type = peekType(); - if (type.isObject()) { //promote strings to objects etc + if (type.isObject() || type.isBoolean()) { //promote strings to objects etc type = Type.OBJECT; convert(Type.OBJECT); //TODO bad- until we specialize boolean setters, } diff --git a/nashorn/test/script/basic/JDK-8026292.js b/nashorn/test/script/basic/JDK-8026292.js new file mode 100644 index 00000000000..740895f2831 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026292.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026292: Megamorphic setter fails with boolean value + * + * @test + * @run + */ + +function megamorphic(o) { + o.w = true; + if (!o.w) + throw new Error(); +} + +// Calls below must exceed megamorphic callsite threshhold +for (var i = 0; i < 10; i++) { + megamorphic({a: 1}); + megamorphic({b: 1}); + megamorphic({c: 1}); + megamorphic({d: 1}); + megamorphic({e: 1}); + megamorphic({f: 1}); + megamorphic({g: 1}); + megamorphic({h: 1}); + megamorphic({i: 1}); + megamorphic({j: 1}); + megamorphic({k: 1}); + megamorphic({l: 1}); + megamorphic({m: 1}); + megamorphic({n: 1}); + megamorphic({o: 1}); + megamorphic({p: 1}); + megamorphic({q: 1}); + megamorphic({r: 1}); + megamorphic({s: 1}); + megamorphic({t: 1}); + megamorphic({u: 1}); + megamorphic({v: 1}); + megamorphic({w: 1}); + megamorphic({x: 1}); + megamorphic({y: 1}); + megamorphic({z: 1}); +} From a71c4a53907824e06361b5229f07c327be2e41e8 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 11 Oct 2013 11:15:59 +0200 Subject: [PATCH 052/152] 8026302: source representation of getter and setter methods is wrong Reviewed-by: lagergren, hannesw, jlaskey --- .../jdk/nashorn/internal/parser/Parser.java | 2 +- nashorn/test/script/basic/JDK-8026302.js | 48 +++++++++++++++++++ .../test/script/basic/JDK-8026302.js.EXPECTED | 10 ++++ nashorn/test/script/basic/objects.js.EXPECTED | 8 ++-- 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026302.js create mode 100644 nashorn/test/script/basic/JDK-8026302.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index c19d4367c7a..869746cf05c 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -2107,7 +2107,7 @@ loop: final String ident = (String)expectValue(IDENT); if (type != COLON) { - final long getSetToken = token; + final long getSetToken = propertyToken; switch (ident) { case "get": diff --git a/nashorn/test/script/basic/JDK-8026302.js b/nashorn/test/script/basic/JDK-8026302.js new file mode 100644 index 00000000000..786cc118675 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026302.js @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026302: source representation of getter and setter methods is wrong + * + * @test + * @run + */ + +var obj = { + get "foo"() {}, + set "foo"(x) {}, + get bar() {}, + set bar(x) {}, + get ":"() {}, + set ":"(x) {}, + get 12() {}, + set 12(x) {}, + get 1.8e-8() {}, + set 1.8e-8(x) {} +} + +for (var prop in obj) { + var desc = Object.getOwnPropertyDescriptor(obj, prop); + print(desc.get); + print(desc.set); +} diff --git a/nashorn/test/script/basic/JDK-8026302.js.EXPECTED b/nashorn/test/script/basic/JDK-8026302.js.EXPECTED new file mode 100644 index 00000000000..232edc007d0 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026302.js.EXPECTED @@ -0,0 +1,10 @@ +get "foo"() {} +set "foo"(x) {} +get bar() {} +set bar(x) {} +get ":"() {} +set ":"(x) {} +get 12() {} +set 12(x) {} +get 1.8e-8() {} +set 1.8e-8(x) {} diff --git a/nashorn/test/script/basic/objects.js.EXPECTED b/nashorn/test/script/basic/objects.js.EXPECTED index a6bedc098f6..d59daa8737f 100644 --- a/nashorn/test/script/basic/objects.js.EXPECTED +++ b/nashorn/test/script/basic/objects.js.EXPECTED @@ -29,18 +29,18 @@ abc is writable? undefined abc is configurable? true abc is enumerable? true abc's value = undefined -abc's get = abc() { return "abc"; } +abc's get = get abc() { return "abc"; } abc's set = undefined xyz is writable? undefined xyz is configurable? true xyz is enumerable? true xyz's value = undefined xyz's get = undefined -xyz's set = xyz(val) { print(val); } +xyz's set = set xyz(val) { print(val); } hey is writable? undefined hey is configurable? true hey is enumerable? true hey's value = undefined -hey's get = hey() { return "hey"; } -hey's set = hey(val) { print(val); } +hey's get = get hey() { return "hey"; } +hey's set = set hey(val) { print(val); } undefined From 9215790d61b64cf6f3a403a9595570cc6c51322f Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Fri, 11 Oct 2013 13:10:22 +0200 Subject: [PATCH 053/152] 8011415: CTW on Sparc: assert(lrg.lo_degree()) failed: Increased the LRG AllStack mask size since the previous size was not big enough when compiling huge methods (60k+ nodes) Reviewed-by: kvn, roland, twisti --- hotspot/src/share/vm/opto/chaitin.hpp | 18 +++++++++++++----- hotspot/src/share/vm/opto/ifg.cpp | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index 41276efa5ca..da98d16e29c 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -52,6 +52,7 @@ class PhaseChaitin; class LRG : public ResourceObj { friend class VMStructs; public: + static const uint AllStack_size = 0xFFFFF; // This mask size is used to tell that the mask of this LRG supports stack positions enum { SPILL_REG=29999 }; // Register number of a spilled LRG double _cost; // 2 for loads/1 for stores times block freq @@ -80,14 +81,21 @@ public: private: uint _eff_degree; // Effective degree: Sum of neighbors _num_regs public: - int degree() const { assert( _degree_valid, "" ); return _eff_degree; } + int degree() const { assert( _degree_valid , "" ); return _eff_degree; } // Degree starts not valid and any change to the IFG neighbor // set makes it not valid. - void set_degree( uint degree ) { _eff_degree = degree; debug_only(_degree_valid = 1;) } + void set_degree( uint degree ) { + _eff_degree = degree; + debug_only(_degree_valid = 1;) + assert(!_mask.is_AllStack() || (_mask.is_AllStack() && lo_degree()), "_eff_degree can't be bigger than AllStack_size - _num_regs if the mask supports stack registers"); + } // Made a change that hammered degree void invalid_degree() { debug_only(_degree_valid=0;) } // Incrementally modify degree. If it was correct, it should remain correct - void inc_degree( uint mod ) { _eff_degree += mod; } + void inc_degree( uint mod ) { + _eff_degree += mod; + assert(!_mask.is_AllStack() || (_mask.is_AllStack() && lo_degree()), "_eff_degree can't be bigger than AllStack_size - _num_regs if the mask supports stack registers"); + } // Compute the degree between 2 live ranges int compute_degree( LRG &l ) const; @@ -95,9 +103,9 @@ private: RegMask _mask; // Allowed registers for this LRG uint _mask_size; // cache of _mask.Size(); public: - int compute_mask_size() const { return _mask.is_AllStack() ? 65535 : _mask.Size(); } + int compute_mask_size() const { return _mask.is_AllStack() ? AllStack_size : _mask.Size(); } void set_mask_size( int size ) { - assert((size == 65535) || (size == (int)_mask.Size()), ""); + assert((size == (int)AllStack_size) || (size == (int)_mask.Size()), ""); _mask_size = size; #ifdef ASSERT _msize_valid=1; diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index db8dbea84d7..89ed5b33102 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -677,7 +677,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { } else { // Common case: size 1 bound removal if( lrg.mask().Member(r_reg) ) { lrg.Remove(r_reg); - lrg.set_mask_size(lrg.mask().is_AllStack() ? 65535:old_size-1); + lrg.set_mask_size(lrg.mask().is_AllStack() ? LRG::AllStack_size : old_size - 1); } } // If 'l' goes completely dry, it must spill. From 7f46feeee2aafbd7ef9f919d2e93fc2624074ec5 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Fri, 11 Oct 2013 10:14:02 -0700 Subject: [PATCH 054/152] 8005173: assert(false) failed: DEBUG MESSAGE: exception oop must be empty (macroAssembler_x86.cpp:625) Reviewed-by: kvn, iveresov --- .../src/cpu/sparc/vm/c1_Runtime1_sparc.cpp | 19 ++++++++++++ hotspot/src/share/vm/c1/c1_Runtime1.cpp | 3 +- hotspot/src/share/vm/opto/runtime.cpp | 29 ++++++++++++------- hotspot/src/share/vm/runtime/thread.hpp | 5 ++++ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index bc633103586..01a4a0267d6 100644 --- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -1067,6 +1067,25 @@ OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) { __ verify_not_null_oop(Oexception); +#ifdef ASSERT + // check that fields in JavaThread for exception oop and issuing pc are + // empty before writing to them + Label oop_empty; + Register scratch = I7; // We can use I7 here because it's overwritten later anyway. + __ ld_ptr(Address(G2_thread, JavaThread::exception_oop_offset()), scratch); + __ br_null(scratch, false, Assembler::pt, oop_empty); + __ delayed()->nop(); + __ stop("exception oop already set"); + __ bind(oop_empty); + + Label pc_empty; + __ ld_ptr(Address(G2_thread, JavaThread::exception_pc_offset()), scratch); + __ br_null(scratch, false, Assembler::pt, pc_empty); + __ delayed()->nop(); + __ stop("exception pc already set"); + __ bind(pc_empty); +#endif + // save the exception and issuing pc in the thread __ st_ptr(Oexception, G2_thread, in_bytes(JavaThread::exception_oop_offset())); __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset())); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 8c48c8b0cb5..e3bac09c5b4 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -542,8 +542,7 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t // exception handler can cause class loading, which might throw an // exception and those fields are expected to be clear during // normal bytecode execution. - thread->set_exception_oop(NULL); - thread->set_exception_pc(NULL); + thread->clear_exception_oop_and_pc(); continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false); // If an exception was thrown during exception dispatch, the exception oop may have changed diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index 9a278c5ac1c..173a735c9ba 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -976,30 +976,36 @@ JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* t address handler_address = NULL; Handle exception(thread, thread->exception_oop()); + address pc = thread->exception_pc(); + + // Clear out the exception oop and pc since looking up an + // exception handler can cause class loading, which might throw an + // exception and those fields are expected to be clear during + // normal bytecode execution. + thread->clear_exception_oop_and_pc(); if (TraceExceptions) { - trace_exception(exception(), thread->exception_pc(), ""); + trace_exception(exception(), pc, ""); } + // for AbortVMOnException flag NOT_PRODUCT(Exceptions::debug_check_abort(exception)); - #ifdef ASSERT - if (!(exception->is_a(SystemDictionary::Throwable_klass()))) { - // should throw an exception here - ShouldNotReachHere(); - } - #endif - +#ifdef ASSERT + if (!(exception->is_a(SystemDictionary::Throwable_klass()))) { + // should throw an exception here + ShouldNotReachHere(); + } +#endif // new exception handling: this method is entered only from adapters // exceptions from compiled java methods are handled in compiled code // using rethrow node - address pc = thread->exception_pc(); nm = CodeCache::find_nmethod(pc); assert(nm != NULL, "No NMethod found"); if (nm->is_native_method()) { - fatal("Native mathod should not have path to exception handling"); + fatal("Native method should not have path to exception handling"); } else { // we are switching to old paradigm: search for exception handler in caller_frame // instead in exception handler of caller_frame.sender() @@ -1346,7 +1352,8 @@ static void trace_exception(oop exception_oop, address exception_pc, const char* tty->print(" in "); CodeBlob* blob = CodeCache::find_blob(exception_pc); if (blob->is_nmethod()) { - ((nmethod*)blob)->method()->print_value(); + nmethod* nm = blob->as_nmethod_or_null(); + nm->method()->print_value(); } else if (blob->is_runtime_stub()) { tty->print(""); } else { diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 4d46cfadbaf..d9a757eb434 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -1283,6 +1283,11 @@ class JavaThread: public Thread { void set_exception_handler_pc(address a) { _exception_handler_pc = a; } void set_is_method_handle_return(bool value) { _is_method_handle_return = value ? 1 : 0; } + void clear_exception_oop_and_pc() { + set_exception_oop(NULL); + set_exception_pc(NULL); + } + // Stack overflow support inline size_t stack_available(address cur_sp); address stack_yellow_zone_base() From c8bfc7e7d7e0286bf09b5aa5b5200279c67044f1 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Sat, 12 Oct 2013 12:12:59 +0200 Subject: [PATCH 055/152] 8026054: New type profiling points: type of return values at calls X86 interpreter and c1 type profiling for return values at calls Reviewed-by: kvn, twisti --- hotspot/src/cpu/x86/vm/globals_x86.hpp | 2 +- hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp | 106 +++-- hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp | 1 + hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp | 103 +++-- hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp | 1 + .../cpu/x86/vm/templateInterpreter_x86_32.cpp | 6 + .../cpu/x86/vm/templateInterpreter_x86_64.cpp | 6 + hotspot/src/share/vm/c1/c1_Canonicalizer.cpp | 1 + hotspot/src/share/vm/c1/c1_Canonicalizer.hpp | 1 + hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 35 ++ hotspot/src/share/vm/c1/c1_GraphBuilder.hpp | 1 + hotspot/src/share/vm/c1/c1_Instruction.hpp | 34 ++ .../src/share/vm/c1/c1_InstructionPrinter.cpp | 6 + .../src/share/vm/c1/c1_InstructionPrinter.hpp | 1 + hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 19 +- hotspot/src/share/vm/c1/c1_LIRGenerator.hpp | 1 + hotspot/src/share/vm/c1/c1_Optimizer.cpp | 7 + .../share/vm/c1/c1_RangeCheckElimination.hpp | 1 + hotspot/src/share/vm/c1/c1_ValueMap.hpp | 1 + hotspot/src/share/vm/ci/ciMethodData.cpp | 54 ++- hotspot/src/share/vm/ci/ciMethodData.hpp | 69 +++- hotspot/src/share/vm/oops/methodData.cpp | 186 +++++++-- hotspot/src/share/vm/oops/methodData.hpp | 383 ++++++++++++------ hotspot/src/share/vm/runtime/globals.hpp | 5 +- 24 files changed, 814 insertions(+), 216 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp index 8e8c42fabb6..a727e077bd6 100644 --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp @@ -79,7 +79,7 @@ define_pd_global(bool, UseMembar, false); // GC Ergo Flags define_pd_global(uintx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread -define_pd_global(uintx, TypeProfileLevel, 1); +define_pd_global(uintx, TypeProfileLevel, 11); #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \ \ diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp index 1a602ae8c09..183defa8784 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp @@ -1095,7 +1095,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca return; } - if (MethodData::profile_arguments()) { + if (MethodData::profile_arguments() || MethodData::profile_return()) { Label profile_continue; test_method_data_pointer(mdp, profile_continue); @@ -1105,35 +1105,95 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); jcc(Assembler::notEqual, profile_continue); - Label done; - int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset()); - addptr(mdp, off_to_args); + if (MethodData::profile_arguments()) { + Label done; + int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); + addptr(mdp, off_to_args); - for (int i = 0; i < TypeProfileArgsLimit; i++) { - if (i > 0) { - movl(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args)); - subl(tmp, i*TypeStackSlotEntries::per_arg_count()); - cmpl(tmp, TypeStackSlotEntries::per_arg_count()); - jcc(Assembler::less, done); + for (int i = 0; i < TypeProfileArgsLimit; i++) { + if (i > 0 || MethodData::profile_return()) { + // If return value type is profiled we may have no argument to profile + movl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); + subl(tmp, i*TypeStackSlotEntries::per_arg_count()); + cmpl(tmp, TypeStackSlotEntries::per_arg_count()); + jcc(Assembler::less, done); + } + movptr(tmp, Address(callee, Method::const_offset())); + load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); + // stack offset o (zero based) from the start of the argument + // list, for n arguments translates into offset n - o - 1 from + // the end of the argument list + subl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args)); + subl(tmp, 1); + Address arg_addr = argument_address(tmp); + movptr(tmp, arg_addr); + + Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args); + profile_obj_type(tmp, mdo_arg_addr); + + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); + addptr(mdp, to_add); + off_to_args += to_add; } - movptr(tmp, Address(callee, Method::const_offset())); - load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); - subl(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args)); - subl(tmp, 1); - Address arg_addr = argument_address(tmp); - movptr(tmp, arg_addr); - Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args); - profile_obj_type(tmp, mdo_arg_addr); + if (MethodData::profile_return()) { + movl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); + subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); + } - int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); - addptr(mdp, to_add); - off_to_args += to_add; + bind(done); + + if (MethodData::profile_return()) { + // We're right after the type profile for the last + // argument. tmp is the number of cell left in the + // CallTypeData/VirtualCallTypeData to reach its end. Non null + // if there's a return to profile. + assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); + shll(tmp, exact_log2(DataLayout::cell_size)); + addptr(mdp, tmp); + } + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); + } else { + assert(MethodData::profile_return(), "either profile call args or call ret"); + update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size())); } - bind(done); + // mdp points right after the end of the + // CallTypeData/VirtualCallTypeData, right after the cells for the + // return value type if there's one - movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); + bind(profile_continue); + } +} + +void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) { + assert_different_registers(mdp, ret, tmp, rsi); + if (ProfileInterpreter && MethodData::profile_return()) { + Label profile_continue, done; + + test_method_data_pointer(mdp, profile_continue); + + if (MethodData::profile_return_jsr292_only()) { + // If we don't profile all invoke bytecodes we must make sure + // it's a bytecode we indeed profile. We can't go back to the + // begining of the ProfileData we intend to update to check its + // type because we're right after it and we don't known its + // length + Label do_profile; + cmpb(Address(rsi, 0), Bytecodes::_invokedynamic); + jcc(Assembler::equal, do_profile); + cmpb(Address(rsi, 0), Bytecodes::_invokehandle); + jcc(Assembler::equal, do_profile); + get_method(tmp); + cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm); + jcc(Assembler::notEqual, profile_continue); + + bind(do_profile); + } + + Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size())); + mov(tmp, ret); + profile_obj_type(tmp, mdo_ret_addr); bind(profile_continue); } diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp index 6ccac4a126e..91f0aa1bc41 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp @@ -217,6 +217,7 @@ class InterpreterMacroAssembler: public MacroAssembler { void profile_not_taken_branch(Register mdp); void profile_obj_type(Register obj, const Address& mdo_addr); void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual); + void profile_return_type(Register mdp, Register ret, Register tmp); void profile_call(Register mdp); void profile_final_call(Register mdp); void profile_virtual_call(Register receiver, Register mdp, Register scratch2, diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp index 28c7c8b383f..8495f0da130 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp @@ -1120,7 +1120,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca return; } - if (MethodData::profile_arguments()) { + if (MethodData::profile_arguments() || MethodData::profile_return()) { Label profile_continue; test_method_data_pointer(mdp, profile_continue); @@ -1130,35 +1130,92 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); jcc(Assembler::notEqual, profile_continue); - Label done; - int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset()); - addptr(mdp, off_to_args); + if (MethodData::profile_arguments()) { + Label done; + int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); + addptr(mdp, off_to_args); - for (int i = 0; i < TypeProfileArgsLimit; i++) { - if (i > 0) { - movq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args)); - subl(tmp, i*TypeStackSlotEntries::per_arg_count()); - cmpl(tmp, TypeStackSlotEntries::per_arg_count()); - jcc(Assembler::less, done); + for (int i = 0; i < TypeProfileArgsLimit; i++) { + if (i > 0 || MethodData::profile_return()) { + // If return value type is profiled we may have no argument to profile + movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); + subl(tmp, i*TypeStackSlotEntries::per_arg_count()); + cmpl(tmp, TypeStackSlotEntries::per_arg_count()); + jcc(Assembler::less, done); + } + movptr(tmp, Address(callee, Method::const_offset())); + load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); + subq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args)); + subl(tmp, 1); + Address arg_addr = argument_address(tmp); + movptr(tmp, arg_addr); + + Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args); + profile_obj_type(tmp, mdo_arg_addr); + + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); + addptr(mdp, to_add); + off_to_args += to_add; } - movptr(tmp, Address(callee, Method::const_offset())); - load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); - subq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args)); - subl(tmp, 1); - Address arg_addr = argument_address(tmp); - movptr(tmp, arg_addr); - Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args); - profile_obj_type(tmp, mdo_arg_addr); + if (MethodData::profile_return()) { + movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); + subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); + } - int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); - addptr(mdp, to_add); - off_to_args += to_add; + bind(done); + + if (MethodData::profile_return()) { + // We're right after the type profile for the last + // argument. tmp is the number of cell left in the + // CallTypeData/VirtualCallTypeData to reach its end. Non null + // if there's a return to profile. + assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); + shll(tmp, exact_log2(DataLayout::cell_size)); + addptr(mdp, tmp); + } + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); + } else { + assert(MethodData::profile_return(), "either profile call args or call ret"); + update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size())); } - bind(done); + // mdp points right after the end of the + // CallTypeData/VirtualCallTypeData, right after the cells for the + // return value type if there's one - movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); + bind(profile_continue); + } +} + +void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) { + assert_different_registers(mdp, ret, tmp, r13); + if (ProfileInterpreter && MethodData::profile_return()) { + Label profile_continue, done; + + test_method_data_pointer(mdp, profile_continue); + + if (MethodData::profile_return_jsr292_only()) { + // If we don't profile all invoke bytecodes we must make sure + // it's a bytecode we indeed profile. We can't go back to the + // begining of the ProfileData we intend to update to check its + // type because we're right after it and we don't known its + // length + Label do_profile; + cmpb(Address(r13, 0), Bytecodes::_invokedynamic); + jcc(Assembler::equal, do_profile); + cmpb(Address(r13, 0), Bytecodes::_invokehandle); + jcc(Assembler::equal, do_profile); + get_method(tmp); + cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm); + jcc(Assembler::notEqual, profile_continue); + + bind(do_profile); + } + + Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size())); + mov(tmp, ret); + profile_obj_type(tmp, mdo_ret_addr); bind(profile_continue); } diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp index 2e1ea945c1d..fe7b76039f9 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp @@ -226,6 +226,7 @@ class InterpreterMacroAssembler: public MacroAssembler { void profile_not_taken_branch(Register mdp); void profile_obj_type(Register obj, const Address& mdo_addr); void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual); + void profile_return_type(Register mdp, Register ret, Register tmp); void profile_call(Register mdp); void profile_final_call(Register mdp); void profile_virtual_call(Register receiver, Register mdp, diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 52e459900c7..7d9af3e6404 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -194,6 +194,12 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, __ restore_bcp(); __ restore_locals(); + if (incoming_state == atos) { + Register mdp = rbx; + Register tmp = rcx; + __ profile_return_type(mdp, rax, tmp); + } + Label L_got_cache, L_giant_index; if (EnableInvokeDynamic) { __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic); diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index 6648bcd08bf..d7e0d7742b0 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -177,6 +177,12 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, __ restore_bcp(); __ restore_locals(); + if (state == atos) { + Register mdp = rbx; + Register tmp = rcx; + __ profile_return_type(mdp, rax, tmp); + } + Label L_got_cache, L_giant_index; if (EnableInvokeDynamic) { __ cmpb(Address(r13, 0), Bytecodes::_invokedynamic); diff --git a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp index b80b199c9c2..f98edc6f563 100644 --- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp +++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp @@ -935,6 +935,7 @@ void Canonicalizer::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void Canonicalizer::do_ProfileCall(ProfileCall* x) {} +void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {} void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {} void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {} void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {} diff --git a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp index 9e34ac79a31..43ce4a41c14 100644 --- a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp +++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp @@ -104,6 +104,7 @@ class Canonicalizer: InstructionVisitor { virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); + virtual void do_ProfileReturnType (ProfileReturnType* x); virtual void do_ProfileInvoke (ProfileInvoke* x); virtual void do_RuntimeCall (RuntimeCall* x); virtual void do_MemBar (MemBar* x); diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index f93a6e89050..23d800528b3 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -1466,9 +1466,22 @@ void GraphBuilder::method_return(Value x) { // State at end of inlined method is the state of the caller // without the method parameters on stack, including the // return value, if any, of the inlined method on operand stack. + int invoke_bci = state()->caller_state()->bci(); set_state(state()->caller_state()->copy_for_parsing()); if (x != NULL) { state()->push(x->type(), x); + if (profile_calls() && MethodData::profile_return() && x->type()->is_object_kind()) { + ciMethod* caller = state()->scope()->method(); + ciMethodData* md = caller->method_data_or_null(); + ciProfileData* data = md->bci_to_data(invoke_bci); + if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { + bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return(); + // May not be true in case of an inlined call through a method handle intrinsic. + if (has_return) { + profile_return_type(x, method(), caller, invoke_bci); + } + } + } } Goto* goto_callee = new Goto(continuation(), false); @@ -2008,6 +2021,9 @@ void GraphBuilder::invoke(Bytecodes::Code code) { push(result_type, result); } } + if (profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) { + profile_return_type(result, target); + } } @@ -3556,6 +3572,10 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { Value value = append_split(result); if (result_type != voidType) push(result_type, value); + if (callee != method() && profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) { + profile_return_type(result, callee); + } + // done return true; } @@ -4312,6 +4332,21 @@ void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_hol append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); } +void GraphBuilder::profile_return_type(Value ret, ciMethod* callee, ciMethod* m, int invoke_bci) { + assert((m == NULL) == (invoke_bci < 0), "invalid method and invalid bci together"); + if (m == NULL) { + m = method(); + } + if (invoke_bci < 0) { + invoke_bci = bci(); + } + ciMethodData* md = m->method_data_or_null(); + ciProfileData* data = md->bci_to_data(invoke_bci); + if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { + append(new ProfileReturnType(m , invoke_bci, callee, ret)); + } +} + void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { append(new ProfileInvoke(callee, state)); } diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp index 217da78bb26..7945674fc4e 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp @@ -375,6 +375,7 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { void print_inlining(ciMethod* callee, const char* msg = NULL, bool success = true); void profile_call(ciMethod* callee, Value recv, ciKlass* predicted_holder, Values* obj_args, bool inlined); + void profile_return_type(Value ret, ciMethod* callee, ciMethod* m = NULL, int bci = -1); void profile_invocation(ciMethod* inlinee, ValueStack* state); // Shortcuts to profiling control. diff --git a/hotspot/src/share/vm/c1/c1_Instruction.hpp b/hotspot/src/share/vm/c1/c1_Instruction.hpp index 466d814c674..19490bbc97b 100644 --- a/hotspot/src/share/vm/c1/c1_Instruction.hpp +++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp @@ -107,6 +107,7 @@ class UnsafePrefetch; class UnsafePrefetchRead; class UnsafePrefetchWrite; class ProfileCall; +class ProfileReturnType; class ProfileInvoke; class RuntimeCall; class MemBar; @@ -211,6 +212,7 @@ class InstructionVisitor: public StackObj { virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x) = 0; virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; virtual void do_ProfileCall (ProfileCall* x) = 0; + virtual void do_ProfileReturnType (ProfileReturnType* x) = 0; virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; virtual void do_RuntimeCall (RuntimeCall* x) = 0; virtual void do_MemBar (MemBar* x) = 0; @@ -2518,6 +2520,38 @@ LEAF(ProfileCall, Instruction) } }; +LEAF(ProfileReturnType, Instruction) + private: + ciMethod* _method; + ciMethod* _callee; + int _bci_of_invoke; + Value _ret; + + public: + ProfileReturnType(ciMethod* method, int bci, ciMethod* callee, Value ret) + : Instruction(voidType) + , _method(method) + , _callee(callee) + , _bci_of_invoke(bci) + , _ret(ret) + { + set_needs_null_check(true); + // The ProfileType has side-effects and must occur precisely where located + pin(); + } + + ciMethod* method() const { return _method; } + ciMethod* callee() const { return _callee; } + int bci_of_invoke() const { return _bci_of_invoke; } + Value ret() const { return _ret; } + + virtual void input_values_do(ValueVisitor* f) { + if (_ret != NULL) { + f->visit(&_ret); + } + } +}; + // Call some C runtime function that doesn't safepoint, // optionally passing the current thread as the first argument. LEAF(RuntimeCall, Instruction) diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp index c15538116fd..7f87e1183b0 100644 --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp @@ -904,6 +904,12 @@ void InstructionPrinter::do_ProfileCall(ProfileCall* x) { output()->put(')'); } +void InstructionPrinter::do_ProfileReturnType(ProfileReturnType* x) { + output()->print("profile ret type "); + print_value(x->ret()); + output()->print(" %s.%s", x->method()->holder()->name()->as_utf8(), x->method()->name()->as_utf8()); + output()->put(')'); +} void InstructionPrinter::do_ProfileInvoke(ProfileInvoke* x) { output()->print("profile_invoke "); output()->print(" %s.%s", x->inlinee()->holder()->name()->as_utf8(), x->inlinee()->name()->as_utf8()); diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp index 8c80b6c7507..2ad20d3e65a 100644 --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp @@ -132,6 +132,7 @@ class InstructionPrinter: public InstructionVisitor { virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); + virtual void do_ProfileReturnType (ProfileReturnType* x); virtual void do_ProfileInvoke (ProfileInvoke* x); virtual void do_RuntimeCall (RuntimeCall* x); virtual void do_MemBar (MemBar* x); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index 3eedf1f313a..40bccf8ef77 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -3089,7 +3089,7 @@ void LIRGenerator::profile_arguments(ProfileCall* x) { Bytecodes::Code bc = x->method()->java_code_at_bci(bci); int start = 0; - int stop = args->number_of_arguments(); + int stop = data->is_CallTypeData() ? ((ciCallTypeData*)data)->number_of_arguments() : ((ciVirtualCallTypeData*)data)->number_of_arguments(); if (x->nb_profiled_args() < stop) { // if called through method handle invoke, some arguments may have been popped stop = x->nb_profiled_args(); @@ -3099,7 +3099,7 @@ void LIRGenerator::profile_arguments(ProfileCall* x) { bool has_receiver = x->inlined() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc); ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL); for (int i = 0; i < stop; i++) { - int off = in_bytes(TypeStackSlotEntries::type_offset(i)) - in_bytes(TypeStackSlotEntries::args_data_offset()); + int off = in_bytes(TypeEntriesAtCall::argument_type_offset(i)) - in_bytes(TypeEntriesAtCall::args_data_offset()); ciKlass* exact = profile_arg_type(md, base_offset, off, args->type(i), x->profiled_arg_at(i+start), mdp, !x->arg_needs_null_check(i+start), sig_stream.next_klass()); @@ -3131,6 +3131,21 @@ void LIRGenerator::do_ProfileCall(ProfileCall* x) { __ profile_call(x->method(), x->bci_of_invoke(), x->callee(), mdo, recv, tmp, x->known_holder()); } +void LIRGenerator::do_ProfileReturnType(ProfileReturnType* x) { + int bci = x->bci_of_invoke(); + ciMethodData* md = x->method()->method_data_or_null(); + ciProfileData* data = md->bci_to_data(bci); + assert(data->is_CallTypeData() || data->is_VirtualCallTypeData(), "wrong profile data type"); + ciReturnTypeEntry* ret = data->is_CallTypeData() ? ((ciCallTypeData*)data)->ret() : ((ciVirtualCallTypeData*)data)->ret(); + LIR_Opr mdp = LIR_OprFact::illegalOpr; + ciKlass* exact = profile_arg_type(md, 0, md->byte_offset_of_slot(data, ret->type_offset()), + ret->type(), x->ret(), mdp, + !x->needs_null_check(), x->callee()->signature()->return_type()->as_klass()); + if (exact != NULL) { + md->set_return_type(bci, exact); + } +} + void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) { // We can safely ignore accessors here, since c2 will inline them anyway, // accessors are also always mature. diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp index fce938a03d8..05399e59046 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp @@ -536,6 +536,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); + virtual void do_ProfileReturnType (ProfileReturnType* x); virtual void do_ProfileInvoke (ProfileInvoke* x); virtual void do_RuntimeCall (RuntimeCall* x); virtual void do_MemBar (MemBar* x); diff --git a/hotspot/src/share/vm/c1/c1_Optimizer.cpp b/hotspot/src/share/vm/c1/c1_Optimizer.cpp index 0be6099aa61..90667b46f39 100644 --- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp +++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp @@ -531,6 +531,7 @@ public: void do_UnsafePrefetchRead (UnsafePrefetchRead* x); void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); void do_ProfileCall (ProfileCall* x); + void do_ProfileReturnType (ProfileReturnType* x); void do_ProfileInvoke (ProfileInvoke* x); void do_RuntimeCall (RuntimeCall* x); void do_MemBar (MemBar* x); @@ -658,6 +659,7 @@ class NullCheckEliminator: public ValueVisitor { void handle_ExceptionObject (ExceptionObject* x); void handle_Phi (Phi* x); void handle_ProfileCall (ProfileCall* x); + void handle_ProfileReturnType (ProfileReturnType* x); }; @@ -718,6 +720,7 @@ void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); nce()->handle_ProfileCall(x); } +void NullCheckVisitor::do_ProfileReturnType (ProfileReturnType* x) { nce()->handle_ProfileReturnType(x); } void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {} void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {} void NullCheckVisitor::do_MemBar (MemBar* x) {} @@ -1142,6 +1145,10 @@ void NullCheckEliminator::handle_ProfileCall(ProfileCall* x) { } } +void NullCheckEliminator::handle_ProfileReturnType(ProfileReturnType* x) { + x->set_needs_null_check(!set_contains(x->ret())); +} + void Optimizer::eliminate_null_checks() { ResourceMark rm; diff --git a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp index 1d7897bda9a..b022a81374b 100644 --- a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp +++ b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp @@ -162,6 +162,7 @@ public: void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }; void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }; void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }; + void do_ProfileReturnType (ProfileReturnType* x) { /* nothing to do */ }; void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; void do_MemBar (MemBar* x) { /* nothing to do */ }; diff --git a/hotspot/src/share/vm/c1/c1_ValueMap.hpp b/hotspot/src/share/vm/c1/c1_ValueMap.hpp index 820d1909efa..1404aa0b8a8 100644 --- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp +++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp @@ -203,6 +203,7 @@ class ValueNumberingVisitor: public InstructionVisitor { void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ } void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ } void do_ProfileCall (ProfileCall* x) { /* nothing to do */ } + void do_ProfileReturnType (ProfileReturnType* x) { /* nothing to do */ } void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; void do_MemBar (MemBar* x) { /* nothing to do */ }; diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index fb06759154a..aae7d92c29a 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -137,12 +137,17 @@ void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) { void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) { - for (int i = 0; i < number_of_arguments(); i++) { + for (int i = 0; i < _number_of_entries; i++) { intptr_t k = entries->type(i); TypeStackSlotEntries::set_type(i, translate_klass(k)); } } +void ciReturnTypeEntry::translate_type_data_from(const ReturnTypeEntry* ret) { + intptr_t k = ret->type(); + set_type(translate_klass(k)); +} + // Get the data at an arbitrary (sort of) data index. ciProfileData* ciMethodData::data_at(int data_index) { if (out_of_bounds(data_index)) { @@ -313,6 +318,20 @@ void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) { } } +void ciMethodData::set_return_type(int bci, ciKlass* k) { + VM_ENTRY_MARK; + MethodData* mdo = get_MethodData(); + if (mdo != NULL) { + ProfileData* data = mdo->bci_to_data(bci); + if (data->is_CallTypeData()) { + data->as_CallTypeData()->set_return_type(k->get_Klass()); + } else { + assert(data->is_VirtualCallTypeData(), "no arguments!"); + data->as_VirtualCallTypeData()->set_return_type(k->get_Klass()); + } + } +} + bool ciMethodData::has_escape_info() { return eflag_set(MethodData::estimated); } @@ -517,9 +536,7 @@ void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) { } void ciTypeStackSlotEntries::print_data_on(outputStream* st) const { - _pd->tab(st, true); - st->print("argument types"); - for (int i = 0; i < number_of_arguments(); i++) { + for (int i = 0; i < _number_of_entries; i++) { _pd->tab(st); st->print("%d: stack (%u) ", i, stack_slot(i)); print_ciklass(st, type(i)); @@ -527,9 +544,25 @@ void ciTypeStackSlotEntries::print_data_on(outputStream* st) const { } } +void ciReturnTypeEntry::print_data_on(outputStream* st) const { + _pd->tab(st); + st->print("ret "); + print_ciklass(st, type()); + st->cr(); +} + void ciCallTypeData::print_data_on(outputStream* st) const { print_shared(st, "ciCallTypeData"); - args()->print_data_on(st); + if (has_arguments()) { + tab(st, true); + st->print("argument types"); + args()->print_data_on(st); + } + if (has_return()) { + tab(st, true); + st->print("return type"); + ret()->print_data_on(st); + } } void ciReceiverTypeData::print_receiver_data_on(outputStream* st) const { @@ -561,6 +594,15 @@ void ciVirtualCallData::print_data_on(outputStream* st) const { void ciVirtualCallTypeData::print_data_on(outputStream* st) const { print_shared(st, "ciVirtualCallTypeData"); rtd_super()->print_receiver_data_on(st); - args()->print_data_on(st); + if (has_arguments()) { + tab(st, true); + st->print("argument types"); + args()->print_data_on(st); + } + if (has_return()) { + tab(st, true); + st->print("return type"); + ret()->print_data_on(st); + } } #endif diff --git a/hotspot/src/share/vm/ci/ciMethodData.hpp b/hotspot/src/share/vm/ci/ciMethodData.hpp index 8de598117a6..b57ab6deeec 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.hpp +++ b/hotspot/src/share/vm/ci/ciMethodData.hpp @@ -104,20 +104,55 @@ public: #endif }; +class ciReturnTypeEntry : public ReturnTypeEntry, ciTypeEntries { +public: + void translate_type_data_from(const ReturnTypeEntry* ret); + + ciKlass* valid_type() const { + return valid_ciklass(type()); + } + +#ifndef PRODUCT + void print_data_on(outputStream* st) const; +#endif +}; + class ciCallTypeData : public CallTypeData { public: ciCallTypeData(DataLayout* layout) : CallTypeData(layout) {} ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)CallTypeData::args(); } + ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)CallTypeData::ret(); } - virtual void translate_from(const ProfileData* data) { - args()->translate_type_data_from(data->as_CallTypeData()->args()); + void translate_type_data_from(const ProfileData* data) { + if (has_arguments()) { + args()->translate_type_data_from(data->as_CallTypeData()->args()); + } + if (has_return()) { + ret()->translate_type_data_from(data->as_CallTypeData()->ret()); + } + } + + intptr_t argument_type(int i) const { + assert(has_arguments(), "no arg type profiling data"); + return args()->type(i); } ciKlass* valid_argument_type(int i) const { + assert(has_arguments(), "no arg type profiling data"); return args()->valid_type(i); } + intptr_t return_type() const { + assert(has_return(), "no ret type profiling data"); + return ret()->type(); + } + + ciKlass* valid_return_type() const { + assert(has_return(), "no ret type profiling data"); + return ret()->valid_type(); + } + #ifndef PRODUCT void print_data_on(outputStream* st) const; #endif @@ -179,12 +214,9 @@ class ciVirtualCallTypeData : public VirtualCallTypeData { private: // Fake multiple inheritance... It's a ciReceiverTypeData also. ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; } - public: ciVirtualCallTypeData(DataLayout* layout) : VirtualCallTypeData(layout) {} - ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); } - void set_receiver(uint row, ciKlass* recv) { rtd_super()->set_receiver(row, recv); } @@ -193,16 +225,40 @@ public: return rtd_super()->receiver(row); } + ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); } + ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)VirtualCallTypeData::ret(); } + // Copy & translate from oop based VirtualCallData virtual void translate_from(const ProfileData* data) { rtd_super()->translate_receiver_data_from(data); - args()->translate_type_data_from(data->as_VirtualCallTypeData()->args()); + if (has_arguments()) { + args()->translate_type_data_from(data->as_VirtualCallTypeData()->args()); + } + if (has_return()) { + ret()->translate_type_data_from(data->as_VirtualCallTypeData()->ret()); + } + } + + intptr_t argument_type(int i) const { + assert(has_arguments(), "no arg type profiling data"); + return args()->type(i); } ciKlass* valid_argument_type(int i) const { + assert(has_arguments(), "no arg type profiling data"); return args()->valid_type(i); } + intptr_t return_type() const { + assert(has_return(), "no ret type profiling data"); + return ret()->type(); + } + + ciKlass* valid_return_type() const { + assert(has_return(), "no ret type profiling data"); + return ret()->valid_type(); + } + #ifndef PRODUCT void print_data_on(outputStream* st) const; #endif @@ -347,6 +403,7 @@ public: // If the compiler finds a profiled type that is known statically // for sure, set it in the MethodData void set_argument_type(int bci, int i, ciKlass* k); + void set_return_type(int bci, ciKlass* k); void load_data(); diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index efb45934d7e..e50107f29e3 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -156,16 +156,31 @@ void JumpData::print_data_on(outputStream* st) const { } #endif // !PRODUCT -int TypeStackSlotEntries::compute_cell_count(BytecodeStream* stream) { - int max = TypeProfileArgsLimit; - assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); - Bytecode_invoke inv(stream->method(), stream->bci()); - +int TypeStackSlotEntries::compute_cell_count(Symbol* signature, int max) { ResourceMark rm; - SignatureStream ss(inv.signature()); + SignatureStream ss(signature); int args_count = MIN2(ss.reference_parameter_count(), max); + return args_count * per_arg_cell_count; +} - return args_count * per_arg_cell_count + (args_count > 0 ? header_cell_count() : 0); +int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) { + assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); + assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken"); + Bytecode_invoke inv(stream->method(), stream->bci()); + int args_cell = 0; + if (arguments_profiling_enabled()) { + args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), TypeProfileArgsLimit); + } + int ret_cell = 0; + if (return_profiling_enabled() && (inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY)) { + ret_cell = ReturnTypeEntry::static_cell_count(); + } + int header_cell = 0; + if (args_cell + ret_cell > 0) { + header_cell = header_cell_count(); + } + + return header_cell + args_cell + ret_cell; } class ArgumentOffsetComputer : public SignatureInfo { @@ -197,26 +212,55 @@ public: int off_at(int i) const { return _offsets.at(i); } }; -void TypeStackSlotEntries::post_initialize(BytecodeStream* stream) { +void TypeStackSlotEntries::post_initialize(Symbol* signature, bool has_receiver) { ResourceMark rm; + ArgumentOffsetComputer aos(signature, _number_of_entries); + aos.total(); + for (int i = 0; i < _number_of_entries; i++) { + set_stack_slot(i, aos.off_at(i) + (has_receiver ? 1 : 0)); + set_type(i, type_none()); + } +} +void CallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); Bytecode_invoke inv(stream->method(), stream->bci()); -#ifdef ASSERT SignatureStream ss(inv.signature()); - int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); - assert(count > 0, "room for args type but none found?"); - check_number_of_arguments(count); + if (has_arguments()) { +#ifdef ASSERT + ResourceMark rm; + int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); + assert(count > 0, "room for args type but none found?"); + check_number_of_arguments(count); #endif + _args.post_initialize(inv.signature(), inv.has_receiver()); + } - int start = 0; - ArgumentOffsetComputer aos(inv.signature(), number_of_arguments()-start); - aos.total(); - bool has_receiver = inv.has_receiver(); - for (int i = start; i < number_of_arguments(); i++) { - set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); - set_type(i, type_none()); + if (has_return()) { + assert(inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY, "room for a ret type but doesn't return obj?"); + _ret.post_initialize(); + } +} + +void VirtualCallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { + assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); + Bytecode_invoke inv(stream->method(), stream->bci()); + + if (has_arguments()) { +#ifdef ASSERT + ResourceMark rm; + SignatureStream ss(inv.signature()); + int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); + assert(count > 0, "room for args type but none found?"); + check_number_of_arguments(count); +#endif + _args.post_initialize(inv.signature(), inv.has_receiver()); + } + + if (has_return()) { + assert(inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY, "room for a ret type but doesn't return obj?"); + _ret.post_initialize(); } } @@ -226,7 +270,7 @@ bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) { } void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { - for (int i = 0; i < number_of_arguments(); i++) { + for (int i = 0; i < _number_of_entries; i++) { intptr_t p = type(i); if (is_loader_alive(is_alive_cl, p)) { set_type(i, type_none()); @@ -234,7 +278,18 @@ void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl } } -bool TypeStackSlotEntries::arguments_profiling_enabled() { +void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { + intptr_t p = type(); + if (is_loader_alive(is_alive_cl, p)) { + set_type(type_none()); + } +} + +bool TypeEntriesAtCall::return_profiling_enabled() { + return MethodData::profile_return(); +} + +bool TypeEntriesAtCall::arguments_profiling_enabled() { return MethodData::profile_arguments(); } @@ -253,9 +308,7 @@ void TypeEntries::print_klass(outputStream* st, intptr_t k) { } void TypeStackSlotEntries::print_data_on(outputStream* st) const { - _pd->tab(st, true); - st->print("argument types"); - for (int i = 0; i < number_of_arguments(); i++) { + for (int i = 0; i < _number_of_entries; i++) { _pd->tab(st); st->print("%d: stack(%u) ", i, stack_slot(i)); print_klass(st, type(i)); @@ -263,14 +316,38 @@ void TypeStackSlotEntries::print_data_on(outputStream* st) const { } } +void ReturnTypeEntry::print_data_on(outputStream* st) const { + _pd->tab(st); + print_klass(st, type()); + st->cr(); +} + void CallTypeData::print_data_on(outputStream* st) const { CounterData::print_data_on(st); - _args.print_data_on(st); + if (has_arguments()) { + tab(st, true); + st->print("argument types"); + _args.print_data_on(st); + } + if (has_return()) { + tab(st, true); + st->print("return type"); + _ret.print_data_on(st); + } } void VirtualCallTypeData::print_data_on(outputStream* st) const { VirtualCallData::print_data_on(st); - _args.print_data_on(st); + if (has_arguments()) { + tab(st, true); + st->print("argument types"); + _args.print_data_on(st); + } + if (has_return()) { + tab(st, true); + st->print("return type"); + _ret.print_data_on(st); + } } #endif @@ -530,7 +607,7 @@ int MethodData::bytecode_cell_count(Bytecodes::Code code) { } case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: - if (MethodData::profile_arguments()) { + if (MethodData::profile_arguments() || MethodData::profile_return()) { return variable_cell_count; } else { return CounterData::static_cell_count(); @@ -542,13 +619,13 @@ int MethodData::bytecode_cell_count(Bytecodes::Code code) { return JumpData::static_cell_count(); case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: - if (MethodData::profile_arguments()) { + if (MethodData::profile_arguments() || MethodData::profile_return()) { return variable_cell_count; } else { return VirtualCallData::static_cell_count(); } case Bytecodes::_invokedynamic: - if (MethodData::profile_arguments()) { + if (MethodData::profile_arguments() || MethodData::profile_return()) { return variable_cell_count; } else { return CounterData::static_cell_count(); @@ -596,8 +673,9 @@ int MethodData::compute_data_size(BytecodeStream* stream) { case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: case Bytecodes::_invokedynamic: - assert(MethodData::profile_arguments(), "should be collecting args profile"); - if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + assert(MethodData::profile_arguments() || MethodData::profile_return(), "should be collecting args profile"); + if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = CallTypeData::compute_cell_count(stream); } else { cell_count = CounterData::static_cell_count(); @@ -605,8 +683,9 @@ int MethodData::compute_data_size(BytecodeStream* stream) { break; case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: { - assert(MethodData::profile_arguments(), "should be collecting args profile"); - if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + assert(MethodData::profile_arguments() || MethodData::profile_return(), "should be collecting args profile"); + if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = VirtualCallTypeData::compute_cell_count(stream); } else { cell_count = VirtualCallData::static_cell_count(); @@ -699,7 +778,8 @@ int MethodData::initialize_data(BytecodeStream* stream, case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: { int counter_data_cell_count = CounterData::static_cell_count(); - if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = CallTypeData::compute_cell_count(stream); } else { cell_count = counter_data_cell_count; @@ -721,7 +801,8 @@ int MethodData::initialize_data(BytecodeStream* stream, case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: { int virtual_call_data_cell_count = VirtualCallData::static_cell_count(); - if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = VirtualCallTypeData::compute_cell_count(stream); } else { cell_count = virtual_call_data_cell_count; @@ -736,7 +817,8 @@ int MethodData::initialize_data(BytecodeStream* stream, case Bytecodes::_invokedynamic: { // %%% should make a type profile for any invokedynamic that takes a ref argument int counter_data_cell_count = CounterData::static_cell_count(); - if (profile_arguments_for_invoke(stream->method(), stream->bci())) { + if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = CallTypeData::compute_cell_count(stream); } else { cell_count = counter_data_cell_count; @@ -778,7 +860,7 @@ int MethodData::initialize_data(BytecodeStream* stream, break; } assert(tag == DataLayout::multi_branch_data_tag || - (MethodData::profile_arguments() && + ((MethodData::profile_arguments() || MethodData::profile_return()) && (tag == DataLayout::call_type_data_tag || tag == DataLayout::counter_data_tag || tag == DataLayout::virtual_call_type_data_tag || @@ -1111,7 +1193,7 @@ bool MethodData::profile_jsr292(methodHandle m, int bci) { } int MethodData::profile_arguments_flag() { - return TypeProfileLevel; + return TypeProfileLevel % 10; } bool MethodData::profile_arguments() { @@ -1139,3 +1221,31 @@ bool MethodData::profile_arguments_for_invoke(methodHandle m, int bci) { return profile_jsr292(m, bci); } +int MethodData::profile_return_flag() { + return TypeProfileLevel / 10; +} + +bool MethodData::profile_return() { + return profile_return_flag() > no_type_profile && profile_return_flag() <= type_profile_all; +} + +bool MethodData::profile_return_jsr292_only() { + return profile_return_flag() == type_profile_jsr292; +} + +bool MethodData::profile_all_return() { + return profile_return_flag() == type_profile_all; +} + +bool MethodData::profile_return_for_invoke(methodHandle m, int bci) { + if (!profile_return()) { + return false; + } + + if (profile_all_return()) { + return true; + } + + assert(profile_return_jsr292_only(), "inconsistent"); + return profile_jsr292(m, bci); +} diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 2064d4365d6..1dc6272c66f 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -271,6 +271,7 @@ class ArgInfoData; // data in a structured way. class ProfileData : public ResourceObj { friend class TypeEntries; + friend class ReturnTypeEntry; friend class TypeStackSlotEntries; private: #ifndef PRODUCT @@ -748,119 +749,60 @@ private: per_arg_cell_count }; - // Start with a header if needed. It stores the number of cells used - // for this call type information. Unless we collect only profiling - // for a single argument the number of cells is unknown statically. - static int header_cell_count() { - return (TypeProfileArgsLimit > 1) ? 1 : 0; - } - - static int cell_count_local_offset() { - assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count"); - return 0; - } - - int cell_count_global_offset() const { - return _base_off + cell_count_local_offset(); - } - // offset of cell for stack slot for entry i within ProfileData object - int stack_slot_global_offset(int i) const { + int stack_slot_offset(int i) const { return _base_off + stack_slot_local_offset(i); } - void check_number_of_arguments(int total) { - assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); - } - - // number of cells not counting the header - int cell_count_no_header() const { - return _pd->uint_at(cell_count_global_offset()); - } - - static bool arguments_profiling_enabled(); - static void assert_arguments_profiling_enabled() { - assert(arguments_profiling_enabled(), "args profiling should be on"); - } - protected: + const int _number_of_entries; // offset of cell for type for entry i within ProfileData object - int type_global_offset(int i) const { + int type_offset(int i) const { return _base_off + type_local_offset(i); } public: - TypeStackSlotEntries(int base_off) - : TypeEntries(base_off) {} + TypeStackSlotEntries(int base_off, int nb_entries) + : TypeEntries(base_off), _number_of_entries(nb_entries) {} - static int compute_cell_count(BytecodeStream* stream); + static int compute_cell_count(Symbol* signature, int max); - static void initialize(DataLayout* dl, int base, int cell_count) { - if (TypeProfileArgsLimit > 1) { - int off = base + cell_count_local_offset(); - dl->set_cell_at(off, cell_count - base - header_cell_count()); - } - } - - void post_initialize(BytecodeStream* stream); - - int number_of_arguments() const { - assert_arguments_profiling_enabled(); - if (TypeProfileArgsLimit > 1) { - int cell_count = cell_count_no_header(); - int nb = cell_count / TypeStackSlotEntries::per_arg_count(); - assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args"); - return nb; - } else { - assert(TypeProfileArgsLimit == 1, "at least one arg"); - return 1; - } - } - - int cell_count() const { - assert_arguments_profiling_enabled(); - if (TypeProfileArgsLimit > 1) { - return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset()); - } else { - return _base_off + TypeStackSlotEntries::per_arg_count(); - } - } + void post_initialize(Symbol* signature, bool has_receiver); // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries static int stack_slot_local_offset(int i) { - assert_arguments_profiling_enabled(); - return header_cell_count() + i * per_arg_cell_count + stack_slot_entry; + return i * per_arg_cell_count + stack_slot_entry; } // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries static int type_local_offset(int i) { - return header_cell_count() + i * per_arg_cell_count + type_entry; + return i * per_arg_cell_count + type_entry; } // stack slot for entry i uint stack_slot(int i) const { - assert(i >= 0 && i < number_of_arguments(), "oob"); - return _pd->uint_at(stack_slot_global_offset(i)); + assert(i >= 0 && i < _number_of_entries, "oob"); + return _pd->uint_at(stack_slot_offset(i)); } // set stack slot for entry i void set_stack_slot(int i, uint num) { - assert(i >= 0 && i < number_of_arguments(), "oob"); - _pd->set_uint_at(stack_slot_global_offset(i), num); + assert(i >= 0 && i < _number_of_entries, "oob"); + _pd->set_uint_at(stack_slot_offset(i), num); } // type for entry i intptr_t type(int i) const { - assert(i >= 0 && i < number_of_arguments(), "oob"); - return _pd->intptr_at(type_global_offset(i)); + assert(i >= 0 && i < _number_of_entries, "oob"); + return _pd->intptr_at(type_offset(i)); } // set type for entry i void set_type(int i, intptr_t k) { - assert(i >= 0 && i < number_of_arguments(), "oob"); - _pd->set_intptr_at(type_global_offset(i), k); + assert(i >= 0 && i < _number_of_entries, "oob"); + _pd->set_intptr_at(type_offset(i), k); } static ByteSize per_arg_size() { @@ -871,22 +813,50 @@ public: return per_arg_cell_count ; } - // Code generation support - static ByteSize cell_count_offset() { - return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); - } + // GC support + void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); - static ByteSize args_data_offset() { - return in_ByteSize(header_cell_count() * DataLayout::cell_size); - } +#ifndef PRODUCT + void print_data_on(outputStream* st) const; +#endif +}; - static ByteSize stack_slot_offset(int i) { - return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); - } +// Type entry used for return from a call. A single cell to record the +// type. +class ReturnTypeEntry : public TypeEntries { - static ByteSize type_offset(int i) { - return in_ByteSize(type_local_offset(i) * DataLayout::cell_size); - } +private: + enum { + cell_count = 1 + }; + +public: + ReturnTypeEntry(int base_off) + : TypeEntries(base_off) {} + + void post_initialize() { + set_type(type_none()); + } + + intptr_t type() const { + return _pd->intptr_at(_base_off); + } + + void set_type(intptr_t k) { + _pd->set_intptr_at(_base_off, k); + } + + static int static_cell_count() { + return cell_count; + } + + static ByteSize size() { + return in_ByteSize(cell_count * DataLayout::cell_size); + } + + ByteSize type_offset() { + return DataLayout::cell_offset(_base_off); + } // GC support void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); @@ -896,23 +866,118 @@ public: #endif }; +// Entries to collect type information at a call: contains arguments +// (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a +// number of cells. Because the number of cells for the return type is +// smaller than the number of cells for the type of an arguments, the +// number of cells is used to tell how many arguments are profiled and +// whether a return value is profiled. See has_arguments() and +// has_return(). +class TypeEntriesAtCall { +private: + static int stack_slot_local_offset(int i) { + return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i); + } + + static int argument_type_local_offset(int i) { + return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; + } + +public: + + static int header_cell_count() { + return 1; + } + + static int cell_count_local_offset() { + return 0; + } + + static int compute_cell_count(BytecodeStream* stream); + + static void initialize(DataLayout* dl, int base, int cell_count) { + int off = base + cell_count_local_offset(); + dl->set_cell_at(off, cell_count - base - header_cell_count()); + } + + static bool arguments_profiling_enabled(); + static bool return_profiling_enabled(); + + // Code generation support + static ByteSize cell_count_offset() { + return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); + } + + static ByteSize args_data_offset() { + return in_ByteSize(header_cell_count() * DataLayout::cell_size); + } + + static ByteSize stack_slot_offset(int i) { + return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); + } + + static ByteSize argument_type_offset(int i) { + return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size); + } +}; + // CallTypeData // // A CallTypeData is used to access profiling information about a non -// virtual call for which we collect type information about arguments. +// virtual call for which we collect type information about arguments +// and return value. class CallTypeData : public CounterData { private: + // entries for arguments if any TypeStackSlotEntries _args; + // entry for return type if any + ReturnTypeEntry _ret; + + int cell_count_global_offset() const { + return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); + } + + // number of cells not counting the header + int cell_count_no_header() const { + return uint_at(cell_count_global_offset()); + } + + void check_number_of_arguments(int total) { + assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); + } + +protected: + // An entry for a return value takes less space than an entry for an + // argument so if the number of cells exceeds the number of cells + // needed for an argument, this object contains type information for + // at least one argument. + bool has_arguments() const { + bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); + assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); + return res; + } public: CallTypeData(DataLayout* layout) : - CounterData(layout), _args(CounterData::static_cell_count()) { + CounterData(layout), + _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), + _ret(cell_count() - ReturnTypeEntry::static_cell_count()) + { assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); // Some compilers (VC++) don't want this passed in member initialization list _args.set_profile_data(this); + _ret.set_profile_data(this); } - const TypeStackSlotEntries* args() const { return &_args; } + const TypeStackSlotEntries* args() const { + assert(has_arguments(), "no profiling of arguments"); + return &_args; + } + + const ReturnTypeEntry* ret() const { + assert(has_return(), "no profiling of return value"); + return &_ret; + } virtual bool is_CallTypeData() const { return true; } @@ -921,38 +986,60 @@ public: } static int compute_cell_count(BytecodeStream* stream) { - return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); + return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); } static void initialize(DataLayout* dl, int cell_count) { - TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count); + TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count); } - virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { - _args.post_initialize(stream); - } + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); virtual int cell_count() const { - return _args.cell_count(); + return CounterData::static_cell_count() + + TypeEntriesAtCall::header_cell_count() + + int_at_unchecked(cell_count_global_offset()); } - uint number_of_arguments() const { - return args()->number_of_arguments(); + int number_of_arguments() const { + return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); } void set_argument_type(int i, Klass* k) { + assert(has_arguments(), "no arguments!"); intptr_t current = _args.type(i); _args.set_type(i, TypeEntries::with_status(k, current)); } + void set_return_type(Klass* k) { + assert(has_return(), "no return!"); + intptr_t current = _ret.type(); + _ret.set_type(TypeEntries::with_status(k, current)); + } + + // An entry for a return value takes less space than an entry for an + // argument, so if the remainder of the number of cells divided by + // the number of cells for an argument is not null, a return value + // is profiled in this object. + bool has_return() const { + bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; + assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); + return res; + } + // Code generation support static ByteSize args_data_offset() { - return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); + return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); } // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { - _args.clean_weak_klass_links(is_alive_closure); + if (has_arguments()) { + _args.clean_weak_klass_links(is_alive_closure); + } + if (has_return()) { + _ret.clean_weak_klass_links(is_alive_closure); + } } #ifndef PRODUCT @@ -1105,20 +1192,59 @@ public: // // A VirtualCallTypeData is used to access profiling information about // a virtual call for which we collect type information about -// arguments. +// arguments and return value. class VirtualCallTypeData : public VirtualCallData { private: + // entries for arguments if any TypeStackSlotEntries _args; + // entry for return type if any + ReturnTypeEntry _ret; + + int cell_count_global_offset() const { + return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); + } + + // number of cells not counting the header + int cell_count_no_header() const { + return uint_at(cell_count_global_offset()); + } + + void check_number_of_arguments(int total) { + assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); + } + +protected: + // An entry for a return value takes less space than an entry for an + // argument so if the number of cells exceeds the number of cells + // needed for an argument, this object contains type information for + // at least one argument. + bool has_arguments() const { + bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); + assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); + return res; + } public: VirtualCallTypeData(DataLayout* layout) : - VirtualCallData(layout), _args(VirtualCallData::static_cell_count()) { + VirtualCallData(layout), + _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), + _ret(cell_count() - ReturnTypeEntry::static_cell_count()) + { assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); // Some compilers (VC++) don't want this passed in member initialization list _args.set_profile_data(this); + _ret.set_profile_data(this); } - const TypeStackSlotEntries* args() const { return &_args; } + const TypeStackSlotEntries* args() const { + assert(has_arguments(), "no profiling of arguments"); + return &_args; + } + + const ReturnTypeEntry* ret() const { + assert(has_return(), "no profiling of return value"); + return &_ret; + } virtual bool is_VirtualCallTypeData() const { return true; } @@ -1127,39 +1253,61 @@ public: } static int compute_cell_count(BytecodeStream* stream) { - return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); + return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); } static void initialize(DataLayout* dl, int cell_count) { - TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count); + TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count); } - virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { - _args.post_initialize(stream); - } + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); virtual int cell_count() const { - return _args.cell_count(); + return VirtualCallData::static_cell_count() + + TypeEntriesAtCall::header_cell_count() + + int_at_unchecked(cell_count_global_offset()); } - uint number_of_arguments() const { - return args()->number_of_arguments(); + int number_of_arguments() const { + return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); } void set_argument_type(int i, Klass* k) { + assert(has_arguments(), "no arguments!"); intptr_t current = _args.type(i); _args.set_type(i, TypeEntries::with_status(k, current)); } + void set_return_type(Klass* k) { + assert(has_return(), "no return!"); + intptr_t current = _ret.type(); + _ret.set_type(TypeEntries::with_status(k, current)); + } + + // An entry for a return value takes less space than an entry for an + // argument, so if the remainder of the number of cells divided by + // the number of cells for an argument is not null, a return value + // is profiled in this object. + bool has_return() const { + bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; + assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); + return res; + } + // Code generation support static ByteSize args_data_offset() { - return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); + return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); } // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { ReceiverTypeData::clean_weak_klass_links(is_alive_closure); - _args.clean_weak_klass_links(is_alive_closure); + if (has_arguments()) { + _args.clean_weak_klass_links(is_alive_closure); + } + if (has_return()) { + _ret.clean_weak_klass_links(is_alive_closure); + } } #ifndef PRODUCT @@ -1691,6 +1839,9 @@ private: static bool profile_arguments_jsr292_only(); static bool profile_all_arguments(); static bool profile_arguments_for_invoke(methodHandle m, int bci); + static int profile_return_flag(); + static bool profile_all_return(); + static bool profile_return_for_invoke(methodHandle m, int bci); public: static int header_size() { @@ -1933,6 +2084,8 @@ public: void verify_data_on(outputStream* st); static bool profile_arguments(); + static bool profile_return(); + static bool profile_return_jsr292_only(); }; #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 181ce69a8f4..d39d9863666 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2649,8 +2649,9 @@ class CommandLineFlags { "Enable aggressive optimizations - see arguments.cpp") \ \ product_pd(uintx, TypeProfileLevel, \ - "Type profiling of arguments at call:" \ - "0->off ; 1->js292 only; 2->all methods") \ + "=XY, with Y, Type profiling of arguments at call" \ + " X, Type profiling of return value at call" \ + "X and Y in 0->off ; 1->js292 only; 2->all methods") \ \ product(intx, TypeProfileArgsLimit, 2, \ "max number of call arguments to consider for type profiling") \ From b1d7228bff6c88c8b8e1c342f19f1c72e47e422e Mon Sep 17 00:00:00 2001 From: David Chase Date: Sat, 12 Oct 2013 17:26:41 -0400 Subject: [PATCH 056/152] 8026124: JSR-292 bug: java.nio.file.Path.toString cores dump Catch problem case, assert it matches valid input, new test Reviewed-by: jrose, twisti, kvn --- .../src/share/vm/interpreter/linkResolver.cpp | 17 ++++++++ .../CreatesInterfaceDotEqualsCallInfo.java | 40 +++++++++++++++++++ .../createsInterfaceDotEqualsCallInfo.js | 26 ++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 hotspot/test/compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java create mode 100644 hotspot/test/compiler/jsr292/createsInterfaceDotEqualsCallInfo.js diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 9cebf9115ed..28295380a55 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -1,4 +1,5 @@ /* + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -158,6 +159,22 @@ CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) { index = vt->index_of_miranda(resolved_method->name(), resolved_method->signature()); kind = CallInfo::vtable_call; + } else if (resolved_method->has_vtable_index()) { + // Can occur if an interface redeclares a method of Object. + +#ifdef ASSERT + // Ensure that this is really the case. + KlassHandle object_klass = SystemDictionary::Object_klass(); + Method * object_resolved_method = object_klass()->vtable()->method_at(index); + assert(object_resolved_method->name() == resolved_method->name(), + err_msg("Object and interface method names should match at vtable index %d, %s != %s", + index, object_resolved_method->name()->as_C_string(), resolved_method->name()->as_C_string())); + assert(object_resolved_method->signature() == resolved_method->signature(), + err_msg("Object and interface method signatures should match at vtable index %d, %s != %s", + index, object_resolved_method->signature()->as_C_string(), resolved_method->signature()->as_C_string())); +#endif // ASSERT + + kind = CallInfo::vtable_call; } else { // A regular interface call. kind = CallInfo::itable_call; diff --git a/hotspot/test/compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java b/hotspot/test/compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java new file mode 100644 index 00000000000..0230702d7ed --- /dev/null +++ b/hotspot/test/compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8026124 + * @summary Javascript file provoked assertion failure in linkResolver.cpp + * + * @run main/othervm CreatesInterfaceDotEqualsCallInfo + */ + +public class CreatesInterfaceDotEqualsCallInfo { + public static void main(String[] args) throws java.io.IOException { + String[] jsargs = { System.getProperty("test.src", ".") + + "/createsInterfaceDotEqualsCallInfo.js" }; + jdk.nashorn.tools.Shell.main(System.in, System.out, System.err, jsargs); + System.out.println("PASS, did not crash running Javascript"); + } +} diff --git a/hotspot/test/compiler/jsr292/createsInterfaceDotEqualsCallInfo.js b/hotspot/test/compiler/jsr292/createsInterfaceDotEqualsCallInfo.js new file mode 100644 index 00000000000..9c5b8e617a8 --- /dev/null +++ b/hotspot/test/compiler/jsr292/createsInterfaceDotEqualsCallInfo.js @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +var path = new java.io.File("/Users/someone").toPath(); +path.toString(); From d03157f2cf1458744b91009502f60591ab1b3094 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Mon, 14 Oct 2013 19:30:05 -0700 Subject: [PATCH 057/152] 8026376: assert(false) failed: DEBUG MESSAGE: exception pc already set Reviewed-by: kvn --- hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 3149dbd76d2..62ff0f23b2b 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -3581,6 +3581,7 @@ void SharedRuntime::generate_deopt_blob() { // the pending exception will be picked up the interpreter. __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), Oexception); __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset())); + __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_pc_offset())); __ bind(noException); // deallocate the deoptimization frame taking care to preserve the return values From 83e635a090374756e7ce743b65b8243c6733feb0 Mon Sep 17 00:00:00 2001 From: Staffan Friberg Date: Tue, 15 Oct 2013 12:14:00 -0700 Subject: [PATCH 058/152] 8026293: Schedule part of G1 pre-barrier late Move rare executed part of G1 write barrier from hot path. Reviewed-by: kvn, twisti, roland --- hotspot/src/share/vm/opto/graphKit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 90c98381062..7377053a7ab 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3615,7 +3615,7 @@ void GraphKit::g1_write_barrier_pre(bool do_load, Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); // if (!marking) - __ if_then(marking, BoolTest::ne, zero); { + __ if_then(marking, BoolTest::ne, zero, unlikely); { BasicType index_bt = TypeX_X->basic_type(); assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size."); Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw); From 0e8081e57b50c4897d1d3d26f936236f85b48c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rickard=20B=C3=A4ckman?= Date: Fri, 11 Oct 2013 12:06:14 +0200 Subject: [PATCH 059/152] 8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64 Reviewed-by: kvn, twisti --- hotspot/src/share/vm/opto/compile.cpp | 27 +++++ hotspot/src/share/vm/opto/mathexactnode.cpp | 38 ++++++- hotspot/src/share/vm/opto/mathexactnode.hpp | 11 +- .../intrinsics/mathexact/RepeatTest.java | 107 ++++++++++++++++++ 4 files changed, 176 insertions(+), 7 deletions(-) create mode 100644 hotspot/test/compiler/intrinsics/mathexact/RepeatTest.java diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 0fed4e06c72..19c6a97b24c 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -47,6 +47,7 @@ #include "opto/machnode.hpp" #include "opto/macro.hpp" #include "opto/matcher.hpp" +#include "opto/mathexactnode.hpp" #include "opto/memnode.hpp" #include "opto/mulnode.hpp" #include "opto/node.hpp" @@ -2986,6 +2987,32 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { n->set_req(MemBarNode::Precedent, top()); } break; + // Must set a control edge on all nodes that produce a FlagsProj + // so they can't escape the block that consumes the flags. + // Must also set the non throwing branch as the control + // for all nodes that depends on the result. Unless the node + // already have a control that isn't the control of the + // flag producer + case Op_FlagsProj: + { + MathExactNode* math = (MathExactNode*) n->in(0); + Node* ctrl = math->control_node(); + Node* non_throwing = math->non_throwing_branch(); + math->set_req(0, ctrl); + + Node* result = math->result_node(); + if (result != NULL) { + for (DUIterator_Fast jmax, j = result->fast_outs(jmax); j < jmax; j++) { + Node* out = result->fast_out(j); + if (out->in(0) == NULL) { + out->set_req(0, non_throwing); + } else if (out->in(0) == ctrl) { + out->set_req(0, non_throwing); + } + } + } + } + break; default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" ); diff --git a/hotspot/src/share/vm/opto/mathexactnode.cpp b/hotspot/src/share/vm/opto/mathexactnode.cpp index e15b3360526..7e68daf8ca5 100644 --- a/hotspot/src/share/vm/opto/mathexactnode.cpp +++ b/hotspot/src/share/vm/opto/mathexactnode.cpp @@ -25,9 +25,10 @@ #include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" +#include "opto/cfgnode.hpp" #include "opto/machnode.hpp" -#include "opto/mathexactnode.hpp" #include "opto/matcher.hpp" +#include "opto/mathexactnode.hpp" #include "opto/subnode.hpp" MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) { @@ -36,6 +37,33 @@ MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) { init_req(2, n2); } +BoolNode* MathExactNode::bool_node() const { + Node* flags = flags_node(); + BoolNode* boolnode = flags->unique_out()->as_Bool(); + assert(boolnode != NULL, "must have BoolNode"); + return boolnode; +} + +IfNode* MathExactNode::if_node() const { + BoolNode* boolnode = bool_node(); + IfNode* ifnode = boolnode->unique_out()->as_If(); + assert(ifnode != NULL, "must have IfNode"); + return ifnode; +} + +Node* MathExactNode::control_node() const { + IfNode* ifnode = if_node(); + return ifnode->in(0); +} + +Node* MathExactNode::non_throwing_branch() const { + IfNode* ifnode = if_node(); + if (bool_node()->_test._test == BoolTest::overflow) { + return ifnode->proj_out(0); + } + return ifnode->proj_out(1); +} + Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) { uint ideal_reg = proj->ideal_reg(); RegMask rm; @@ -62,15 +90,15 @@ Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) { } if (flags != NULL) { - BoolNode* bolnode = (BoolNode *) flags->unique_out(); - switch (bolnode->_test._test) { + BoolNode* boolnode = bool_node(); + switch (boolnode->_test._test) { case BoolTest::overflow: // if the check is for overflow - never taken - igvn->replace_node(bolnode, phase->intcon(0)); + igvn->replace_node(boolnode, phase->intcon(0)); break; case BoolTest::no_overflow: // if the check is for no overflow - always taken - igvn->replace_node(bolnode, phase->intcon(1)); + igvn->replace_node(boolnode, phase->intcon(1)); break; default: fatal("Unexpected value of BoolTest"); diff --git a/hotspot/src/share/vm/opto/mathexactnode.hpp b/hotspot/src/share/vm/opto/mathexactnode.hpp index 30d649941a0..b58482a1092 100644 --- a/hotspot/src/share/vm/opto/mathexactnode.hpp +++ b/hotspot/src/share/vm/opto/mathexactnode.hpp @@ -27,8 +27,11 @@ #include "opto/multnode.hpp" #include "opto/node.hpp" +#include "opto/subnode.hpp" #include "opto/type.hpp" +class BoolNode; +class IfNode; class Node; class PhaseGVN; @@ -49,9 +52,13 @@ public: virtual bool is_CFG() const { return false; } virtual uint ideal_reg() const { return NotAMachineReg; } - ProjNode* result_node() { return proj_out(result_proj_node); } - ProjNode* flags_node() { return proj_out(flags_proj_node); } + ProjNode* result_node() const { return proj_out(result_proj_node); } + ProjNode* flags_node() const { return proj_out(flags_proj_node); } + Node* control_node() const; + Node* non_throwing_branch() const; protected: + IfNode* if_node() const; + BoolNode* bool_node() const; Node* no_overflow(PhaseGVN *phase, Node* new_result); }; diff --git a/hotspot/test/compiler/intrinsics/mathexact/RepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/RepeatTest.java new file mode 100644 index 00000000000..aaf63de1d0a --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/RepeatTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025657 + * @summary Test repeating addExact + * @compile RepeatTest.java + * @run main RepeatTest + * + */ + +import java.lang.ArithmeticException; + +public class RepeatTest { + public static void main(String[] args) { + java.util.Random rnd = new java.util.Random(); + for (int i = 0; i < 50000; ++i) { + int x = Integer.MAX_VALUE - 10; + int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5); //rnd.nextInt() / 2; + + int c = rnd.nextInt() / 2; + int d = rnd.nextInt() / 2; + + int a = addExact(x, y); + + if (a != 36) { + throw new RuntimeException("a != 0 : " + a); + } + + int b = nonExact(c, d); + int n = addExact2(c, d); + + + if (n != b) { + throw new RuntimeException("n != b : " + n + " != " + b); + } + } + } + + public static int addExact2(int x, int y) { + int result = 0; + result += java.lang.Math.addExact(x, y); + result += java.lang.Math.addExact(x, y); + result += java.lang.Math.addExact(x, y); + result += java.lang.Math.addExact(x, y); + return result; + } + + public static int addExact(int x, int y) { + int result = 0; + try { + result += 5; + result = java.lang.Math.addExact(x, y); + } catch (ArithmeticException e) { + result += 1; + } + try { + result += 6; + + result += java.lang.Math.addExact(x, y); + } catch (ArithmeticException e) { + result += 2; + } + try { + result += 7; + result += java.lang.Math.addExact(x, y); + } catch (ArithmeticException e) { + result += 3; + } + try { + result += 8; + result += java.lang.Math.addExact(x, y); + } catch (ArithmeticException e) { + result += 4; + } + return result; + } + + public static int nonExact(int x, int y) { + int result = x + y; + result += x + y; + result += x + y; + result += x + y; + return result; + } +} From 44c3da1ed0a803acc23ecff2b49907ecef8bca86 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Fri, 11 Oct 2013 13:48:02 +0200 Subject: [PATCH 060/152] 8026199: serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java Compilation failed Fixed a compilation failure due to changed method name Reviewed-by: sla, jbachorik --- .../sa/jmap-hprof/JMapHProfLargeHeapTest.java | 4 ++-- .../com/oracle/java/testlibrary/JDKToolLauncher.java | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java index 37d7b709be7..df6ecb28f14 100644 --- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java +++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java @@ -59,7 +59,7 @@ public class JMapHProfLargeHeapTest { // If we are on MacOSX, test if JMap tool is signed, otherwise return // since test will fail with privilege error. if (Platform.isOSX()) { - String jmapToolPath = JDKToolFinder.getCurrentJDKTool("jmap"); + String jmapToolPath = JDKToolFinder.getTestJDKTool("jmap"); ProcessBuilder codesignProcessBuilder = new ProcessBuilder( "codesign", "-v", jmapToolPath); Process codesignProcess = codesignProcessBuilder.start(); @@ -107,7 +107,7 @@ public class JMapHProfLargeHeapTest { System.out.println("Extracted pid: " + pid); JDKToolLauncher jMapLauncher = JDKToolLauncher - .create("jmap", false); + .createUsingTestJDK("jmap"); jMapLauncher.addToolArg("-dump:format=b,file=" + pid + "-" + HEAP_DUMP_FILE_NAME); jMapLauncher.addToolArg(String.valueOf(pid)); diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java index 29df4a776e6..7871bd2ce2f 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java @@ -56,7 +56,7 @@ public class JDKToolLauncher { if (useCompilerJDK) { executable = JDKToolFinder.getJDKTool(tool); } else { - executable = JDKToolFinder.getCurrentJDKTool(tool); + executable = JDKToolFinder.getTestJDKTool(tool); } vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs())); } @@ -74,17 +74,15 @@ public class JDKToolLauncher { } /** - * Creates a new JDKToolLauncher for the specified tool. + * Creates a new JDKToolLauncher for the specified tool in the Tested JDK. * * @param tool * The name of the tool - * @param useCompilerPath - * If true use the compiler JDK path, otherwise use the tested - * JDK path. + * * @return A new JDKToolLauncher */ - public static JDKToolLauncher create(String tool, boolean useCompilerJDK) { - return new JDKToolLauncher(tool, useCompilerJDK); + public static JDKToolLauncher createUsingTestJDK(String tool) { + return new JDKToolLauncher(tool, false); } /** From 7f0264f5485f644cffbbb8a91eb4dc4e4cd49edf Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Fri, 11 Oct 2013 14:08:02 +0200 Subject: [PATCH 061/152] 8024425: VM_HeapDumper doesn't put anonymous classes in the heap dump Switched from using SystemDictionary to using ClassLoaderDataGraph to get the anonymous classes included. Reviewed-by: sla, sspitsyn --- hotspot/src/share/vm/services/heapDumper.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp index 5622fad053f..c0d01048924 100644 --- a/hotspot/src/share/vm/services/heapDumper.cpp +++ b/hotspot/src/share/vm/services/heapDumper.cpp @@ -1545,7 +1545,9 @@ void VM_HeapDumper::do_load_class(Klass* k) { // writes a HPROF_GC_CLASS_DUMP record for the given class void VM_HeapDumper::do_class_dump(Klass* k) { - DumperSupport::dump_class_and_array_classes(writer(), k); + if (k->oop_is_instance()) { + DumperSupport::dump_class_and_array_classes(writer(), k); + } } // writes a HPROF_GC_CLASS_DUMP records for a given basic type @@ -1722,7 +1724,7 @@ void VM_HeapDumper::doit() { SymbolTable::symbols_do(&sym_dumper); // write HPROF_LOAD_CLASS records - SystemDictionary::classes_do(&do_load_class); + ClassLoaderDataGraph::classes_do(&do_load_class); Universe::basic_type_classes_do(&do_load_class); // write HPROF_FRAME and HPROF_TRACE records @@ -1733,7 +1735,7 @@ void VM_HeapDumper::doit() { write_dump_header(); // Writes HPROF_GC_CLASS_DUMP records - SystemDictionary::classes_do(&do_class_dump); + ClassLoaderDataGraph::classes_do(&do_class_dump); Universe::basic_type_classes_do(&do_basic_type_array_class_dump); check_segment_length(); From 76d698bbf82f2902ed75f54589835ad29a1a7ba3 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 11 Oct 2013 14:11:14 +0200 Subject: [PATCH 062/152] 8026317: $ in the function name results in wrong function being invoked Reviewed-by: lagergren, jlaskey --- .../nashorn/internal/codegen/Namespace.java | 2 +- nashorn/test/script/basic/JDK-8026317.js | 63 +++++++++++++++++++ .../test/script/basic/JDK-8026317.js.EXPECTED | 2 + 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8026317.js create mode 100644 nashorn/test/script/basic/JDK-8026317.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java b/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java index 5de2fdf847b..72f77a5bfe8 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java @@ -81,7 +81,7 @@ public class Namespace { final int count = counter + 1; namespaceDirectory.put(base, count); - return base + "$" + count; + return base + '-' + count; } } diff --git a/nashorn/test/script/basic/JDK-8026317.js b/nashorn/test/script/basic/JDK-8026317.js new file mode 100644 index 00000000000..57bea9cb56f --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026317.js @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026317: $ in the function name results in wrong function being invoked + * + * @test + * @run + */ + +function case1() { + function g() { + return 0 + } + function g() { + return 1 + } + function g$1() { + return 2 + } + + return g$1() +} + +print(case1()); + +function case2() { + function g() { + return 0 + } + + var h = function g() { + return 1 + } + + function g$1() { + return 2 + } + + return h() +} + +print(case2()); diff --git a/nashorn/test/script/basic/JDK-8026317.js.EXPECTED b/nashorn/test/script/basic/JDK-8026317.js.EXPECTED new file mode 100644 index 00000000000..5f1d0ecea5d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026317.js.EXPECTED @@ -0,0 +1,2 @@ +2 +1 From e0df3515ce189391218a98c6ede4eec646c862df Mon Sep 17 00:00:00 2001 From: James Laskey Date: Fri, 11 Oct 2013 14:54:16 +0200 Subject: [PATCH 063/152] 8026309: latest runsunspider.js tests contains several bugs Reviewed-by: sundar, lagergren --- nashorn/test/script/basic/runsunspider.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nashorn/test/script/basic/runsunspider.js b/nashorn/test/script/basic/runsunspider.js index 84ce915c04f..07d28b76c4b 100644 --- a/nashorn/test/script/basic/runsunspider.js +++ b/nashorn/test/script/basic/runsunspider.js @@ -205,7 +205,7 @@ var tests = [ return ret; }, expected: function() { - return -1.3524862408537381; + return -0.16906933525822856; } }, { name: 'access-binary-trees.js', @@ -213,7 +213,7 @@ var tests = [ return ret; }, expected: function() { - return -4; + return -1; } }, { name: 'access-fannkuch.js', @@ -244,6 +244,7 @@ var tests = [ return 230692593; } }, + /* Test is broken (not initializing dnaOutputString to "") { name: 'regexp-dna.js', actual: function() { return dnaOutputString; @@ -252,6 +253,7 @@ var tests = [ return "agggtaaa|tttaccct 0\n[cgt]gggtaaa|tttaccc[acg] 9\na[act]ggtaaa|tttacc[agt]t 27\nag[act]gtaaa|tttac[agt]ct 24\nagg[act]taaa|ttta[agt]cct 30\naggg[acg]aaa|ttt[cgt]ccct 9\nagggt[cgt]aa|tt[acg]accct 12\nagggta[cgt]a|t[acg]taccct 9\nagggtaa[cgt]|[acg]ttaccct 15\n"; } }, + */ { name: 'math-cordic.js', actual: function() { return total; From 958096d69b2c2a0f621d0c10d2ae3d26018505d9 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 11 Oct 2013 15:49:15 +0200 Subject: [PATCH 064/152] 6278240: Exception from AnnotationValue.getValue() should list the found type not the required type Reviewed-by: darcy, jfranck, jjg --- .../com/sun/tools/javac/code/Type.java | 6 ++ .../com/sun/tools/javac/comp/Annotate.java | 21 ++-- .../com/sun/tools/javac/comp/MemberEnter.java | 2 +- .../Processor.java | 102 ++++++++++++++++++ .../Source.java | 25 +++++ .../Source.out | 7 ++ 6 files changed, 152 insertions(+), 11 deletions(-) create mode 100644 langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Processor.java create mode 100644 langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.java create mode 100644 langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index 269fed3d846..82e9be2be3e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -165,6 +165,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror { return lb.toList(); } + /**For ErrorType, returns the original type, otherwise returns the type itself. + */ + public Type getOriginalType() { + return this; + } + public R accept(Type.Visitor v, S s) { return v.visitType(this, s); } /** Define a type given its tag and type symbol diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index 709d8183b7d..461b7948262 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -37,6 +37,7 @@ import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.TypeTag.ARRAY; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.tree.JCTree.Tag.*; +import javax.lang.model.type.ErrorType; /** Enter annotations on symbols. Annotations accumulate in a queue, * which is processed at the top level of any set of recursive calls @@ -310,7 +311,6 @@ public class Annotate { Attribute enterAttributeValue(Type expected, JCExpression tree, Env env) { - Type original = expected; //first, try completing the attribution value sym - if a completion //error is thrown, we should recover gracefully, and display an //ordinary resolution diagnostic. @@ -351,7 +351,7 @@ public class Annotate { l.head, env); } - return new Attribute.Error(original); + return new Attribute.Error(syms.errType); } if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) { if (tree.hasTag(ANNOTATION)) { @@ -365,12 +365,12 @@ public class Annotate { if (!expected.isErroneous()) log.error(tree.pos(), "annotation.not.valid.for.type", expected); enterAnnotation((JCAnnotation)tree, syms.errType, env); - return new Attribute.Error(original); + return new Attribute.Error(((JCAnnotation)tree).annotationType.type); } if (expected.isPrimitive() || types.isSameType(expected, syms.stringType)) { Type result = attr.attribExpr(tree, env, expected); if (result.isErroneous()) - return new Attribute.Error(expected); + return new Attribute.Error(result.getOriginalType()); if (result.constValue() == null) { log.error(tree.pos(), "attribute.value.must.be.constant"); return new Attribute.Error(expected); @@ -381,14 +381,15 @@ public class Annotate { if (expected.tsym == syms.classType.tsym) { Type result = attr.attribExpr(tree, env, expected); if (result.isErroneous()) { - // Does it look like a class literal? - if (TreeInfo.name(tree) == names._class) { + // Does it look like an unresolved class literal? + if (TreeInfo.name(tree) == names._class && + ((JCFieldAccess) tree).selected.type.isErroneous()) { Name n = (((JCFieldAccess) tree).selected).type.tsym.flatName(); return new Attribute.UnresolvedClass(expected, types.createErrorType(n, syms.unknownSymbol, syms.classType)); } else { - return new Attribute.Error(expected); + return new Attribute.Error(result.getOriginalType()); } } @@ -396,21 +397,21 @@ public class Annotate { // at the tree level if (TreeInfo.name(tree) != names._class) { log.error(tree.pos(), "annotation.value.must.be.class.literal"); - return new Attribute.Error(expected); + return new Attribute.Error(syms.errType); } return new Attribute.Class(types, (((JCFieldAccess) tree).selected).type); } if (expected.hasTag(CLASS) && (expected.tsym.flags() & Flags.ENUM) != 0) { - attr.attribExpr(tree, env, expected); + Type result = attr.attribExpr(tree, env, expected); Symbol sym = TreeInfo.symbol(tree); if (sym == null || TreeInfo.nonstaticSelect(tree) || sym.kind != Kinds.VAR || (sym.flags() & Flags.ENUM) == 0) { log.error(tree.pos(), "enum.annotation.must.be.enum.constant"); - return new Attribute.Error(expected); + return new Attribute.Error(result.getOriginalType()); } VarSymbol enumerator = (VarSymbol) sym; return new Attribute.Enum(expected, enumerator); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 0c997914ed6..e30398ecbe5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -1379,7 +1379,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (!t.hasTag(ERROR)) return t; - return new ErrorType(((ErrorType) t).getOriginalType(), t.tsym) { + return new ErrorType(t.getOriginalType(), t.tsym) { private Type modelType; @Override diff --git a/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Processor.java b/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Processor.java new file mode 100644 index 00000000000..a6e87bac596 --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Processor.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.Writer; +import java.lang.annotation.*; +import java.util.Set; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import javax.lang.model.util.ElementFilter; +import javax.tools.*; +import com.sun.tools.javac.util.Assert; + +public class Processor extends JavacTestingAbstractProcessor { + + private boolean seenGenerated; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (Element e : roundEnv.getElementsAnnotatedWith(Gen.class)) { + Gen gen = e.getAnnotation(Gen.class); + try { + JavaFileObject source = processingEnv.getFiler().createSourceFile(gen.fileName()); + + try (Writer out = source.openWriter()) { + out.write(gen.content()); + } + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + TypeElement generated = processingEnv.getElementUtils().getTypeElement("Generated"); + + if (generated != null) { + Check check = ElementFilter.methodsIn(generated.getEnclosedElements()).get(0).getAnnotation(Check.class); + + checkCorrectException(check::classValue, "java.lang.Class"); + checkCorrectException(check::intConstValue, "boolean"); + checkCorrectException(check::enumValue, "java.lang.String"); + checkCorrectException(check::incorrectAnnotationValue, "java.lang.Deprecated"); + checkCorrectException(check::incorrectArrayValue, ""); + checkCorrectException(check::incorrectClassValue, ""); + + seenGenerated = true; + } + + if (roundEnv.processingOver() && !seenGenerated) { + Assert.error("Did not see the generated class!"); + } + + return true; + } + + private static void checkCorrectException(Runnable runCheck, String expectedType) { + try { + runCheck.run(); + Assert.check(false); //Should not reach here + } catch (AnnotationTypeMismatchException ex) { + Assert.check(expectedType.equals(ex.foundType()), ex.foundType()); + } + } + +} + +@interface Gen { + String fileName(); + String content(); +} + +@interface Check { + Class classValue(); + int intConstValue(); + E enumValue(); + int incorrectAnnotationValue(); + int incorrectArrayValue(); + Class incorrectClassValue(); +} + +enum E { + A; +} diff --git a/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.java b/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.java new file mode 100644 index 00000000000..faa6721766d --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.java @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6278240 + * @summary Ensure AnnotationTypeMismatchException is thrown when appropriate + * with reasonable foundType filled. + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor Processor + * @compile/fail/ref=Source.out -XDrawDiagnostics -processor Processor Source.java + */ + +@Gen(fileName="Generated", + content= +"class Generated {\n" + +" @Check(classValue=String.class,\n" + +" intConstValue=false,\n" + +" enumValue=\"a\",\n" + +" incorrectAnnotationValue=@Deprecated,\n" + +" incorrectArrayValue={1, \"a\"},\n" + +" incorrectClassValue=get())\n" + +" public static Class get() {\n" + +" return null;\n" + +" }\n" + +"}\n") +class Source { +} diff --git a/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.out b/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.out new file mode 100644 index 00000000000..4440550e4f7 --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/EnsureAnnotationTypeMismatchException/Source.out @@ -0,0 +1,7 @@ +Generated.java:2:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Class, java.lang.Class) +Generated.java:3:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: boolean, int) +Generated.java:4:22: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, E) +Generated.java:5:37: compiler.err.annotation.not.valid.for.type: int +Generated.java:6:32: compiler.err.annotation.value.not.allowable.type +Generated.java:7:35: compiler.err.annotation.value.must.be.class.literal +6 errors From d04b304568a8cd6358782bcdbb0090f773a95594 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Fri, 11 Oct 2013 16:18:27 +0200 Subject: [PATCH 065/152] 8024776: Max/MinHeapFreeRatio descriptions should be more precise Descriptions for Max/MinHeapFreeRatio updated Reviewed-by: ehelin, jmasa --- hotspot/src/share/vm/runtime/globals.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index eaf61c90d59..80263392827 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3080,10 +3080,14 @@ class CommandLineFlags { "class pointers are used") \ \ product(uintx, MinHeapFreeRatio, 40, \ - "The minimum percentage of heap free after GC to avoid expansion")\ + "The minimum percentage of heap free after GC to avoid expansion."\ + " For most GCs this applies to the old generation. In G1 it" \ + " applies to the whole heap. Not supported by ParallelGC.") \ \ product(uintx, MaxHeapFreeRatio, 70, \ - "The maximum percentage of heap free after GC to avoid shrinking")\ + "The maximum percentage of heap free after GC to avoid shrinking."\ + " For most GCs this applies to the old generation. In G1 it" \ + " applies to the whole heap. Not supported by ParallelGC.") \ \ product(intx, SoftRefLRUPolicyMSPerMB, 1000, \ "Number of milliseconds per MB of free space in the heap") \ From fa72ad21f9d9f71003e29891e4f66e079ac52487 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 11 Oct 2013 11:23:49 -0400 Subject: [PATCH 066/152] 8022592: assert at constantTag.cpp:57: ShouldNotReachHere() More missing cases for JVM_CONSTANT_Method{Handle,Type}InError Reviewed-by: hseigel, dcubed --- hotspot/src/share/vm/oops/constantPool.cpp | 24 +++---------------- .../src/share/vm/utilities/constantTag.cpp | 15 ++++++++++++ .../src/share/vm/utilities/constantTag.hpp | 3 ++- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index fa13d05d598..73cebb4258f 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -864,32 +864,14 @@ void ConstantPool::unreference_symbols() { } -jbyte normalize_error_tag(jbyte tag) { - switch (tag) { - case JVM_CONSTANT_UnresolvedClassInError: - return JVM_CONSTANT_UnresolvedClass; - case JVM_CONSTANT_MethodHandleInError: - return JVM_CONSTANT_MethodHandle; - case JVM_CONSTANT_MethodTypeInError: - return JVM_CONSTANT_MethodType; - default: - return tag; - } -} - // Compare this constant pool's entry at index1 to the constant pool // cp2's entry at index2. bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS) { - jbyte t1 = tag_at(index1).value(); - jbyte t2 = cp2->tag_at(index2).value(); - - - // JVM_CONSTANT_UnresolvedClassInError tag is equal to JVM_CONSTANT_UnresolvedClass - // when comparing (and the other error tags) - t1 = normalize_error_tag(t1); - t2 = normalize_error_tag(t2); + // The error tags are equivalent to non-error tags when comparing + jbyte t1 = tag_at(index1).non_error_value(); + jbyte t2 = cp2->tag_at(index2).non_error_value(); if (t1 != t2) { // Not the same entry type so there is nothing else to check. Note diff --git a/hotspot/src/share/vm/utilities/constantTag.cpp b/hotspot/src/share/vm/utilities/constantTag.cpp index 25bff0fed6d..7bc55690ac2 100644 --- a/hotspot/src/share/vm/utilities/constantTag.cpp +++ b/hotspot/src/share/vm/utilities/constantTag.cpp @@ -51,7 +51,9 @@ BasicType constantTag::basic_type() const { case JVM_CONSTANT_ClassIndex : case JVM_CONSTANT_StringIndex : case JVM_CONSTANT_MethodHandle : + case JVM_CONSTANT_MethodHandleInError : case JVM_CONSTANT_MethodType : + case JVM_CONSTANT_MethodTypeInError : return T_OBJECT; default: ShouldNotReachHere(); @@ -60,6 +62,19 @@ BasicType constantTag::basic_type() const { } +jbyte constantTag::non_error_value() const { + switch (_tag) { + case JVM_CONSTANT_UnresolvedClassInError: + return JVM_CONSTANT_UnresolvedClass; + case JVM_CONSTANT_MethodHandleInError: + return JVM_CONSTANT_MethodHandle; + case JVM_CONSTANT_MethodTypeInError: + return JVM_CONSTANT_MethodType; + default: + return _tag; + } +} + const char* constantTag::internal_name() const { switch (_tag) { diff --git a/hotspot/src/share/vm/utilities/constantTag.hpp b/hotspot/src/share/vm/utilities/constantTag.hpp index 4865ce21f29..cedddf6a41f 100644 --- a/hotspot/src/share/vm/utilities/constantTag.hpp +++ b/hotspot/src/share/vm/utilities/constantTag.hpp @@ -108,7 +108,8 @@ class constantTag VALUE_OBJ_CLASS_SPEC { _tag = tag; } - jbyte value() { return _tag; } + jbyte value() const { return _tag; } + jbyte non_error_value() const; BasicType basic_type() const; // if used with ldc, what kind of value gets pushed? From 27c290a9695d3a1c6417ac14b85ca4f16937acef Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Fri, 11 Oct 2013 15:33:08 -0400 Subject: [PATCH 067/152] 8026041: JVM crashes with assert "assert(is_updated()) failed: must not be clear" with -XX:+PrintGCApplicationConcurrentTime in -Xcomp mode Prior to printing the time interval in RuntimeService::record_safepoint_begin(), check first that VM initialization is complete. Reviewed-by: coleenp, dholmes, sla, ctornqvi --- hotspot/src/share/vm/services/runtimeService.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/services/runtimeService.cpp b/hotspot/src/share/vm/services/runtimeService.cpp index fc2fdf1f6c0..379b8f3ff9e 100644 --- a/hotspot/src/share/vm/services/runtimeService.cpp +++ b/hotspot/src/share/vm/services/runtimeService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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 @@ -119,7 +119,7 @@ void RuntimeService::record_safepoint_begin() { #endif /* USDT2 */ // Print the time interval in which the app was executing - if (PrintGCApplicationConcurrentTime) { + if (PrintGCApplicationConcurrentTime && _app_timer.is_updated()) { gclog_or_tty->date_stamp(PrintGCDateStamps); gclog_or_tty->stamp(PrintGCTimeStamps); gclog_or_tty->print_cr("Application time: %3.7f seconds", From 7b9107d17386ffdd00685989fa79c8be3e23a498 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 11 Oct 2013 13:14:48 -0700 Subject: [PATCH 068/152] 8026265: new hotspot build - hs25-b55 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index b310fbc0965..51d77f8db50 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=54 +HS_BUILD_NUMBER=55 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From cad4186f29e350119f2ce45b8cd411901834020b Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Fri, 11 Oct 2013 15:20:13 -0700 Subject: [PATCH 069/152] 8025796: hgforest.sh could trigger unbuffered output from hg without complicated machinations Reviewed-by: mduigou --- common/bin/hgforest.sh | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh index 1dc50390b42..2282c3239ca 100644 --- a/common/bin/hgforest.sh +++ b/common/bin/hgforest.sh @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2013, Oracle and/or its affiliates. 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 @@ -27,37 +27,11 @@ command="$1" pull_extra_base="$2" -# Python always buffers stdout significantly, thus we will not see any output from hg clone jdk, -# until a lot of time has passed! By passing -u to python, we get incremental updates -# on stdout. Much nicer. -whichhg="`which hg 2> /dev/null | grep -v '^no hg in'`" - -if [ "${whichhg}" = "" ] ; then - echo Cannot find hg! - exit 1 -fi - if [ "" = "$command" ] ; then echo No command to hg supplied! exit 1 fi -has_hash_bang="`head -n 1 "${whichhg}" | cut -b 1-2`" -python="" -bpython="" - -if [ "#!" = "$has_hash_bang" ] ; then - python="`head -n 1 ${whichhg} | cut -b 3- | sed -e 's/^[ \t]*//;s/[ \t]*$//'`" - bpython="`basename "$python"`" -fi - -if [ -x "$python" -a ! -d "$python" -a "`${python} -V 2>&1 | cut -f 1 -d ' '`" = "Python" ] ; then - hg="${python} -u ${whichhg}" -else - echo Cannot find python from hg launcher. Running plain hg, which probably has buffered stdout. - hg="hg" -fi - # Clean out the temporary directory that stores the pid files. tmp=/tmp/forest.$$ rm -f -r ${tmp} @@ -171,7 +145,7 @@ for i in ${repos} ${repos_extra} ; do ( if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`" - echo ${hg} clone ${pull_newrepo} ${i} + echo hg clone ${pull_newrepo} ${i} path="`dirname ${i}`" if [ "${path}" != "." ] ; then times=0 @@ -184,10 +158,10 @@ for i in ${repos} ${repos_extra} ; do sleep 5 done fi - (${hg} clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc )& + (PYTHONUNBUFFERED=true hg clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc )& else - echo "cd ${i} && ${hg} $*" - cd ${i} && (${hg} "$@"; echo "$?" > ${tmp}/${repopidfile}.pid.rc )& + echo "cd ${i} && hg $*" + cd ${i} && (PYTHONUNBUFFERED=true hg "$@"; echo "$?" > ${tmp}/${repopidfile}.pid.rc )& fi echo $! > ${tmp}/${repopidfile}.pid ) 2>&1 | sed -e "s@^@${reponame}: @") & From 588c91b042bdb7b4837ccd184b32f83db44c7b07 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Sat, 12 Oct 2013 00:49:19 +0200 Subject: [PATCH 070/152] 8023643: G1 assert failed when NewSize was specified greater than MaxNewSize Exit with an error if incompatible NewSize and MaxNeSize are set Reviewed-by: brutisso, tschatzl --- .../src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index cac114b801e..92eee2e8eb9 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -344,6 +344,10 @@ G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size( } } + if (FLAG_IS_CMDLINE(NewSize) && FLAG_IS_CMDLINE(MaxNewSize) && NewSize > MaxNewSize) { + vm_exit_during_initialization("Initial young gen size set larger than the maximum young gen size"); + } + if (FLAG_IS_CMDLINE(NewSize)) { _min_desired_young_length = MAX2((uint) (NewSize / HeapRegion::GrainBytes), 1U); From db171c7b5dcc2c29205c7e2e934b3ee3b8e7072c Mon Sep 17 00:00:00 2001 From: Gerard Ziemski Date: Sat, 12 Oct 2013 13:09:18 -0400 Subject: [PATCH 071/152] 8025942: os::Bsd::available_memory() needs implementation Implement using the host_statistics64() api. Reviewed-by: dsamersoff, morris, dholmes, coleenp, hseigel, dcubed --- hotspot/src/os/bsd/vm/os_bsd.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index fe0ef89d99b..f182b2af88d 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -159,9 +159,21 @@ julong os::available_memory() { return Bsd::available_memory(); } +// available here means free julong os::Bsd::available_memory() { - // XXXBSD: this is just a stopgap implementation - return physical_memory() >> 2; + uint64_t available = physical_memory() >> 2; +#ifdef __APPLE__ + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + vm_statistics64_data_t vmstat; + kern_return_t kerr = host_statistics64(mach_host_self(), HOST_VM_INFO64, + (host_info64_t)&vmstat, &count); + assert(kerr == KERN_SUCCESS, + "host_statistics64 failed - check mach_host_self() and count"); + if (kerr == KERN_SUCCESS) { + available = vmstat.free_count * os::vm_page_size(); + } +#endif + return available; } julong os::physical_memory() { From 7476c45011be48dd684509ff3b4854d1b783ece4 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Sat, 12 Oct 2013 15:39:16 -0400 Subject: [PATCH 072/152] 8024667: VM crashes with "assert(method() != NULL) failed: must have set method" Check if data is in shared spaces before deallocating it. Reviewed-by: coleenp, dcubed --- .../src/share/vm/memory/metadataFactory.hpp | 4 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 42 +++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/vm/memory/metadataFactory.hpp b/hotspot/src/share/vm/memory/metadataFactory.hpp index fce8d9b34d7..9f7a22eaf55 100644 --- a/hotspot/src/share/vm/memory/metadataFactory.hpp +++ b/hotspot/src/share/vm/memory/metadataFactory.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 @@ -65,6 +65,7 @@ class MetadataFactory : AllStatic { static void free_array(ClassLoaderData* loader_data, Array* data) { if (data != NULL) { assert(loader_data != NULL, "shouldn't pass null"); + assert(!data->is_shared(), "cannot deallocate array in shared spaces"); int size = data->size(); if (DumpSharedSpaces) { loader_data->ro_metaspace()->deallocate((MetaWord*)data, size, false); @@ -83,6 +84,7 @@ class MetadataFactory : AllStatic { // Call metadata's deallocate function which will call deallocate fields assert(!DumpSharedSpaces, "cannot deallocate metadata when dumping CDS archive"); assert(!md->on_stack(), "can't deallocate things on stack"); + assert(!md->is_shared(), "cannot deallocate if in shared spaces"); md->deallocate_contents(loader_data); loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size, md->is_klass()); } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index d6a617aa17b..971039ab943 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -320,7 +320,8 @@ InstanceKlass::InstanceKlass(int vtable_len, void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, Array* methods) { - if (methods != NULL && methods != Universe::the_empty_method_array()) { + if (methods != NULL && methods != Universe::the_empty_method_array() && + !methods->is_shared()) { for (int i = 0; i < methods->length(); i++) { Method* method = methods->at(i); if (method == NULL) continue; // maybe null if error processing @@ -344,13 +345,14 @@ void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data, // check that the interfaces don't come from super class Array* sti = (super_klass == NULL) ? NULL : InstanceKlass::cast(super_klass)->transitive_interfaces(); - if (ti != sti) { + if (ti != sti && ti != NULL && !ti->is_shared()) { MetadataFactory::free_array(loader_data, ti); } } // local interfaces can be empty - if (local_interfaces != Universe::the_empty_klass_array()) { + if (local_interfaces != Universe::the_empty_klass_array() && + local_interfaces != NULL && !local_interfaces->is_shared()) { MetadataFactory::free_array(loader_data, local_interfaces); } } @@ -380,21 +382,25 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { deallocate_methods(loader_data, methods()); set_methods(NULL); - if (method_ordering() != Universe::the_empty_int_array()) { + if (method_ordering() != NULL && + method_ordering() != Universe::the_empty_int_array() && + !method_ordering()->is_shared()) { MetadataFactory::free_array(loader_data, method_ordering()); } set_method_ordering(NULL); // default methods can be empty if (default_methods() != NULL && - default_methods() != Universe::the_empty_method_array()) { + default_methods() != Universe::the_empty_method_array() && + !default_methods()->is_shared()) { MetadataFactory::free_array(loader_data, default_methods()); } // Do NOT deallocate the default methods, they are owned by superinterfaces. set_default_methods(NULL); // default methods vtable indices can be empty - if (default_vtable_indices() != NULL) { + if (default_vtable_indices() != NULL && + !default_vtable_indices()->is_shared()) { MetadataFactory::free_array(loader_data, default_vtable_indices()); } set_default_vtable_indices(NULL); @@ -403,8 +409,10 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { // This array is in Klass, but remove it with the InstanceKlass since // this place would be the only caller and it can share memory with transitive // interfaces. - if (secondary_supers() != Universe::the_empty_klass_array() && - secondary_supers() != transitive_interfaces()) { + if (secondary_supers() != NULL && + secondary_supers() != Universe::the_empty_klass_array() && + secondary_supers() != transitive_interfaces() && + !secondary_supers()->is_shared()) { MetadataFactory::free_array(loader_data, secondary_supers()); } set_secondary_supers(NULL); @@ -413,24 +421,32 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { set_transitive_interfaces(NULL); set_local_interfaces(NULL); - MetadataFactory::free_array(loader_data, fields()); + if (fields() != NULL && !fields()->is_shared()) { + MetadataFactory::free_array(loader_data, fields()); + } set_fields(NULL, 0); // If a method from a redefined class is using this constant pool, don't // delete it, yet. The new class's previous version will point to this. if (constants() != NULL) { assert (!constants()->on_stack(), "shouldn't be called if anything is onstack"); - MetadataFactory::free_metadata(loader_data, constants()); + if (!constants()->is_shared()) { + MetadataFactory::free_metadata(loader_data, constants()); + } set_constants(NULL); } - if (inner_classes() != Universe::the_empty_short_array()) { + if (inner_classes() != NULL && + inner_classes() != Universe::the_empty_short_array() && + !inner_classes()->is_shared()) { MetadataFactory::free_array(loader_data, inner_classes()); } set_inner_classes(NULL); - // We should deallocate the Annotations instance - MetadataFactory::free_metadata(loader_data, annotations()); + // We should deallocate the Annotations instance if it's not in shared spaces. + if (annotations() != NULL && !annotations()->is_shared()) { + MetadataFactory::free_metadata(loader_data, annotations()); + } set_annotations(NULL); } From 811bbcded2cf3007c277ecdef097d022eaf41aa7 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Sun, 13 Oct 2013 13:50:16 +0400 Subject: [PATCH 073/152] 8008733: Psr:perf:osb performance regression (18%) in wss_bodyenc Reviewed-by: alanb, shade --- jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java b/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java index e71f61e6243..fd5db6f011e 100644 --- a/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java +++ b/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java @@ -99,8 +99,7 @@ public class XPathContext extends DTMManager // implements ExpressionContext * the DTMManager, it really is a proxy for this object, which * is the real DTMManager. */ - protected DTMManager m_dtmManager = DTMManager.newInstance( - com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()); + protected DTMManager m_dtmManager = null; /** * Return the DTMManager object. Though XPathContext context extends From 3c50f75173654f38d8c4967ea7240a2b214afb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Mon, 14 Oct 2013 11:45:15 +0200 Subject: [PATCH 074/152] 8026016: too many relinks dominate avatar.js http benchmark Reviewed-by: sundar, jlaskey, attila --- .../internal/runtime/ScriptObject.java | 311 ++++++++++-------- nashorn/test/script/basic/JDK-8026016.js | 68 ++++ .../test/script/basic/JDK-8026016.js.EXPECTED | 182 ++++++++++ 3 files changed, 419 insertions(+), 142 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026016.js create mode 100644 nashorn/test/script/basic/JDK-8026016.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index a4ca6017b79..59b50eb0248 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -37,6 +37,8 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.SET; import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE; import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -131,6 +133,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); + static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class); static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); @@ -388,7 +391,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable); } - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -592,7 +595,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * @param value value to define */ protected final void defineOwnProperty(final int index, final Object value) { - assert ArrayIndex.isValidArrayIndex(index) : "invalid array index"; + assert isValidArrayIndex(index) : "invalid array index"; final long longIndex = ArrayIndex.toLongIndex(index); if (longIndex >= getArray().length()) { // make array big enough to hold.. @@ -602,9 +605,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } private void checkIntegerKey(final String key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { @@ -614,7 +617,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } private void removeArraySlot(final String key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -716,6 +719,28 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return null; } + /** + * Low level property API. This is similar to {@link #findProperty(String, boolean)} but returns a + * {@code boolean} value instead of a {@link FindProperty} object. + * @param key Property key. + * @param deep Whether the search should look up proto chain. + * @return true if the property was found. + */ + boolean hasProperty(final String key, final boolean deep) { + if (getMap().findProperty(key) != null) { + return true; + } + + if (deep) { + final ScriptObject myProto = getProto(); + if (myProto != null) { + return myProto.hasProperty(key, deep); + } + } + + return false; + } + /** * Add a new property to the object. *

    @@ -1708,8 +1733,11 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr */ protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); - final FindProperty find = findProperty(name, true); + if (request.isCallSiteUnstable()) { + return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator)); + } + final FindProperty find = findProperty(name, true); MethodHandle methodHandle; if (find == null) { @@ -1727,10 +1755,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr throw new AssertionError(); // never invoked with any other operation } - if (request.isCallSiteUnstable()) { - return findMegaMorphicGetMethod(desc, name); - } - final Class returnType = desc.getMethodType().returnType(); final Property property = find.getProperty(); methodHandle = find.getGetter(returnType); @@ -1757,11 +1781,21 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(proto, name), guard); } - private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) { - final MethodType mhType = desc.getMethodType().insertParameterTypes(1, Object.class); - final GuardedInvocation inv = findGetIndexMethod(mhType); + private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) { + final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod); + final MethodHandle guard = getScriptObjectGuard(desc.getMethodType()); + return new GuardedInvocation(invoker, guard); + } - return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard()); + @SuppressWarnings("unused") + private Object megamorphicGet(final String key, final boolean isMethod) { + final FindProperty find = findProperty(key, true); + + if (find != null) { + return getObjectValue(find); + } + + return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key); } /** @@ -1810,7 +1844,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr */ protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); - if(request.isCallSiteUnstable()) { + if (request.isCallSiteUnstable()) { return findMegaMorphicSetMethod(desc, name); } @@ -2045,6 +2079,26 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return UNDEFINED; } + /** + * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined. + * @param name the method name + * @return the bound function, or undefined + */ + private Object getNoSuchMethod(final String name) { + final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true); + + if (find == null) { + return invokeNoSuchProperty(name); + } + + final Object value = getObjectValue(find); + if (! (value instanceof ScriptFunction)) { + return UNDEFINED; + } + + return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name}); + } + private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) { return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(getMap())); } @@ -2308,7 +2362,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } private int getInt(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2339,7 +2393,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public int getInt(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2351,7 +2405,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public int getInt(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2363,7 +2417,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public int getInt(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2385,7 +2439,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } private long getLong(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2416,7 +2470,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public long getLong(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2428,7 +2482,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public long getLong(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2440,7 +2494,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public long getLong(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2462,7 +2516,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } private double getDouble(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2493,7 +2547,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public double getDouble(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2505,7 +2559,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public double getDouble(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2517,7 +2571,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public double getDouble(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2539,7 +2593,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } private Object get(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2570,7 +2624,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public Object get(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2582,7 +2636,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public Object get(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2594,7 +2648,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public Object get(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2710,9 +2764,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public void set(final Object key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2722,14 +2776,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(key, JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final Object key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2739,14 +2794,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(key, JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final Object key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2756,14 +2812,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(key, JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final Object key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2773,17 +2830,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - final String propName = JSType.toString(key); - final FindProperty find = findProperty(propName, true); - - setObject(find, strict, propName, value); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public void set(final double key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2793,14 +2848,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final double key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2810,14 +2866,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final double key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2827,14 +2884,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final double key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2844,14 +2902,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), value, strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public void set(final long key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2861,14 +2920,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final long key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2878,14 +2938,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final long key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2895,14 +2956,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final long key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2912,14 +2974,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), value, strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public void set(final int key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2929,14 +2992,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final int key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2946,14 +3010,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final int key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2963,14 +3028,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final int key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2980,14 +3046,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - set(JSType.toObject(key), value, strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public boolean has(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -2995,16 +3062,14 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); } @Override public boolean has(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -3012,16 +3077,14 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); } @Override public boolean has(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -3029,16 +3092,14 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); } @Override public boolean has(final int key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -3046,66 +3107,32 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); } @Override public boolean hasOwnProperty(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean hasOwnProperty(final int key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean hasOwnProperty(final long key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean hasOwnProperty(final double key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean delete(final int key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -3121,7 +3148,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public boolean delete(final long key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -3137,7 +3164,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public boolean delete(final double key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -3153,7 +3180,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr @Override public boolean delete(final Object key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { diff --git a/nashorn/test/script/basic/JDK-8026016.js b/nashorn/test/script/basic/JDK-8026016.js new file mode 100644 index 00000000000..43f268d8c4f --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026016.js @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026016: too many relinks dominate avatar.js http benchmark + * + * @test + * @run + */ + +function accessMegamorphic() { + for (var i = 0; i < 26; i++) { + var o = {}; + o[String.fromCharCode(i + 97)] = 1; + o._; + } +} + +function invokeMegamorphic() { + for (var i = 0; i < 26; i++) { + var o = {}; + o[String.fromCharCode(i + 97)] = 1; + try { + o._(i); + } catch (e) { + print(e); + } + } +} + +Object.prototype.__noSuchProperty__ = function() { + print("no such property", Array.prototype.slice.call(arguments)); +}; + +invokeMegamorphic(); +accessMegamorphic(); + +Object.prototype.__noSuchMethod__ = function() { + print("no such method", Array.prototype.slice.call(arguments)); +}; + +invokeMegamorphic(); +accessMegamorphic(); + +Object.prototype.__noSuchMethod__ = "nofunction"; + +invokeMegamorphic(); +accessMegamorphic(); diff --git a/nashorn/test/script/basic/JDK-8026016.js.EXPECTED b/nashorn/test/script/basic/JDK-8026016.js.EXPECTED new file mode 100644 index 00000000000..a2d23834ec8 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026016.js.EXPECTED @@ -0,0 +1,182 @@ +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such method _,0 +no such method _,1 +no such method _,2 +no such method _,3 +no such method _,4 +no such method _,5 +no such method _,6 +no such method _,7 +no such method _,8 +no such method _,9 +no such method _,10 +no such method _,11 +no such method _,12 +no such method _,13 +no such method _,14 +no such method _,15 +no such method _,16 +no such method _,17 +no such method _,18 +no such method _,19 +no such method _,20 +no such method _,21 +no such method _,22 +no such method _,23 +no such method _,24 +no such method _,25 +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ From 3538d0af5544efa2a7da832d332d0140f1e75eac Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Mon, 14 Oct 2013 12:41:11 +0200 Subject: [PATCH 075/152] 8026113: Nashorn arrays should automatically convert to Java arrays Reviewed-by: jlaskey, sundar --- .../jdk/nashorn/internal/runtime/JSType.java | 31 +++ .../linker/JavaArgumentConverters.java | 35 +++- .../api/javaaccess/ArrayConversionTest.java | 191 ++++++++++++++++++ 3 files changed, 252 insertions(+), 5 deletions(-) create mode 100644 nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index 8c79caa7fdc..774295a178d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -31,6 +31,8 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Array; +import java.util.Deque; +import java.util.List; import jdk.internal.dynalink.beans.StaticClass; import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; @@ -110,6 +112,15 @@ public enum JSType { /** Combined call to toPrimitive followed by toString. */ public static final Call TO_PRIMITIVE_TO_STRING = staticCall(myLookup, JSType.class, "toPrimitiveToString", String.class, Object.class); + /** Method handle to convert a JS Object to a Java array. */ + public static final Call TO_JAVA_ARRAY = staticCall(myLookup, JSType.class, "toJavaArray", Object.class, Object.class, Class.class); + + /** Method handle to convert a JS Object to a Java List. */ + public static final Call TO_JAVA_LIST = staticCall(myLookup, JSType.class, "toJavaList", List.class, Object.class); + + /** Method handle to convert a JS Object to a Java deque. */ + public static final Call TO_JAVA_DEQUE = staticCall(myLookup, JSType.class, "toJavaDeque", Deque.class, Object.class); + private static final double INT32_LIMIT = 4294967296.0; /** @@ -890,6 +901,8 @@ public enum JSType { res[idx++] = itr.next(); } return convertArray(res, componentType); + } else if(obj == null) { + return null; } else { throw new IllegalArgumentException("not a script object"); } @@ -918,6 +931,24 @@ public enum JSType { return dst; } + /** + * Converts a JavaScript object to a Java List. See {@link ListAdapter} for details. + * @param obj the object to convert. Can be any array-like object. + * @return a List that is live-backed by the JavaScript object. + */ + public static List toJavaList(final Object obj) { + return ListAdapter.create(obj); + } + + /** + * Converts a JavaScript object to a Java Deque. See {@link ListAdapter} for details. + * @param obj the object to convert. Can be any array-like object. + * @return a Deque that is live-backed by the JavaScript object. + */ + public static Deque toJavaDeque(final Object obj) { + return ListAdapter.create(obj); + } + /** * Check if an object is null or undefined * diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java index f035071b73f..36d15c478a1 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java @@ -25,14 +25,16 @@ package jdk.nashorn.internal.runtime.linker; +import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; -import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.util.HashMap; -import java.util.Map; +import java.util.Deque; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import jdk.internal.dynalink.support.TypeUtilities; import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.JSType; @@ -57,7 +59,13 @@ final class JavaArgumentConverters { } static MethodHandle getConverter(final Class targetType) { - return CONVERTERS.get(targetType); + MethodHandle converter = CONVERTERS.get(targetType); + if(converter == null && targetType.isArray()) { + converter = MH.insertArguments(JSType.TO_JAVA_ARRAY.methodHandle(), 1, targetType.getComponentType()); + converter = MH.asType(converter, converter.type().changeReturnType(targetType)); + CONVERTERS.putIfAbsent(targetType, converter); + } + return converter; } @SuppressWarnings("unused") @@ -211,6 +219,20 @@ final class JavaArgumentConverters { return null; } else if (obj instanceof Long) { return (Long) obj; + } else if (obj instanceof Integer) { + return ((Integer)obj).longValue(); + } else if (obj instanceof Double) { + final Double d = (Double)obj; + if(Double.isInfinite(d.doubleValue())) { + return 0L; + } + return d.longValue(); + } else if (obj instanceof Float) { + final Float f = (Float)obj; + if(Float.isInfinite(f.floatValue())) { + return 0L; + } + return f.longValue(); } else if (obj instanceof Number) { return ((Number)obj).longValue(); } else if (obj instanceof String || obj instanceof ConsString) { @@ -241,9 +263,12 @@ final class JavaArgumentConverters { return MH.findStatic(MethodHandles.lookup(), JavaArgumentConverters.class, name, MH.type(rtype, types)); } - private static final Map, MethodHandle> CONVERTERS = new HashMap<>(); + private static final ConcurrentMap, MethodHandle> CONVERTERS = new ConcurrentHashMap<>(); static { + CONVERTERS.put(List.class, JSType.TO_JAVA_LIST.methodHandle()); + CONVERTERS.put(Deque.class, JSType.TO_JAVA_DEQUE.methodHandle()); + CONVERTERS.put(Number.class, TO_NUMBER); CONVERTERS.put(String.class, TO_STRING); diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java new file mode 100644 index 00000000000..c6794557637 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.Arrays; +import java.util.List; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class ArrayConversionTest { + private static ScriptEngine e = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + e = new ScriptEngineManager().getEngineByName("nashorn"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + } + + @Test + public void testIntArrays() throws ScriptException { + runTest("assertNullIntArray", "null"); + runTest("assertEmptyIntArray", "[]"); + runTest("assertSingle42IntArray", "[42]"); + runTest("assertSingle42IntArray", "['42']"); + runTest("assertIntArrayConversions", "[false, true, NaN, Infinity, -Infinity, 0.4, 0.6, null, undefined, [], {}, [1], [1, 2]]"); + } + + @Test + public void testIntIntArrays() throws ScriptException { + runTest("assertNullIntIntArray", "null"); + runTest("assertEmptyIntIntArray", "[]"); + runTest("assertSingleEmptyIntIntArray", "[[]]"); + runTest("assertSingleNullIntIntArray", "[null]"); + runTest("assertLargeIntIntArray", "[[false], [1], [2, 3], [4, 5, 6], ['7', {valueOf: function() { return 8 }}]]"); + } + + @Test + public void testObjectObjectArrays() throws ScriptException { + runTest("assertLargeObjectObjectArray", "[[false], [1], ['foo', 42.3], [{x: 17}]]"); + } + + @Test + public void testBooleanArrays() throws ScriptException { + runTest("assertBooleanArrayConversions", "[false, true, '', 'false', 0, 1, 0.4, 0.6, {}, [], [false], [true], NaN, Infinity, null, undefined]"); + } + + @Test + public void testListArrays() throws ScriptException { + runTest("assertListArray", "[['foo', 'bar'], ['apple', 'orange']]"); + } + + private static void runTest(final String testMethodName, final String argument) throws ScriptException { + e.eval("Java.type('" + ArrayConversionTest.class.getName() + "')." + testMethodName + "(" + argument + ")"); + } + + public static void assertNullIntArray(int[] array) { + assertNull(array); + } + + public static void assertNullIntIntArray(int[][] array) { + assertNull(array); + } + + public static void assertEmptyIntArray(int[] array) { + assertEquals(0, array.length); + } + + public static void assertSingle42IntArray(int[] array) { + assertEquals(1, array.length); + assertEquals(42, array[0]); + } + + + public static void assertIntArrayConversions(int[] array) { + assertEquals(13, array.length); + assertEquals(0, array[0]); // false + assertEquals(1, array[1]); // true + assertEquals(0, array[2]); // NaN + assertEquals(0, array[3]); // Infinity + assertEquals(0, array[4]); // -Infinity + assertEquals(0, array[5]); // 0.4 + assertEquals(0, array[6]); // 0.6 - floor, not round + assertEquals(0, array[7]); // null + assertEquals(0, array[8]); // undefined + assertEquals(0, array[9]); // [] + assertEquals(0, array[10]); // {} + assertEquals(1, array[11]); // [1] + assertEquals(0, array[12]); // [1, 2] + } + + public static void assertEmptyIntIntArray(int[][] array) { + assertEquals(0, array.length); + } + + public static void assertSingleEmptyIntIntArray(int[][] array) { + assertEquals(1, array.length); + assertTrue(Arrays.equals(new int[0], array[0])); + } + + public static void assertSingleNullIntIntArray(int[][] array) { + assertEquals(1, array.length); + assertNull(null, array[0]); + } + + public static void assertLargeIntIntArray(int[][] array) { + assertEquals(5, array.length); + assertTrue(Arrays.equals(new int[] { 0 }, array[0])); + assertTrue(Arrays.equals(new int[] { 1 }, array[1])); + assertTrue(Arrays.equals(new int[] { 2, 3 }, array[2])); + assertTrue(Arrays.equals(new int[] { 4, 5, 6 }, array[3])); + assertTrue(Arrays.equals(new int[] { 7, 8 }, array[4])); + } + + public static void assertLargeObjectObjectArray(Object[][] array) throws ScriptException { + assertEquals(4, array.length); + assertTrue(Arrays.equals(new Object[] { Boolean.FALSE }, array[0])); + assertTrue(Arrays.equals(new Object[] { 1 }, array[1])); + assertTrue(Arrays.equals(new Object[] { "foo", 42.3d }, array[2])); + assertEquals(1, array[3].length); + e.getBindings(ScriptContext.ENGINE_SCOPE).put("obj", array[3][0]); + assertEquals(17, e.eval("obj.x")); + } + + public static void assertBooleanArrayConversions(boolean[] array) { + assertEquals(16, array.length); + assertFalse(array[0]); // false + assertTrue(array[1]); // true + assertFalse(array[2]); // '' + assertTrue(array[3]); // 'false' (yep, every non-empty string converts to true) + assertFalse(array[4]); // 0 + assertTrue(array[5]); // 1 + assertTrue(array[6]); // 0.4 + assertTrue(array[7]); // 0.6 + assertTrue(array[8]); // {} + assertTrue(array[9]); // [] + assertTrue(array[10]); // [false] + assertTrue(array[11]); // [true] + assertFalse(array[12]); // NaN + assertTrue(array[13]); // Infinity + assertFalse(array[14]); // null + assertFalse(array[15]); // undefined + } + + public static void assertListArray(List[] array) { + assertEquals(2, array.length); + assertEquals(Arrays.asList("foo", "bar"), array[0]); + assertEquals(Arrays.asList("apple", "orange"), array[1]); + } +} From 3e9df3ecf1d76e9e29040f19d89d56774428d6ec Mon Sep 17 00:00:00 2001 From: Stefan Johansson Date: Mon, 14 Oct 2013 14:21:34 +0200 Subject: [PATCH 076/152] 8025661: Ill-formed -Xminf and -Xmaxf options values interpreted as 0 Using strtod() instead of atof() when parsing -Xminf and -Xmaxf. Reviewed-by: brutisso, pliden --- hotspot/src/share/vm/runtime/arguments.cpp | 10 +- .../test/gc/arguments/TestHeapFreeRatio.java | 105 ++++++++++++++++++ 2 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 hotspot/test/gc/arguments/TestHeapFreeRatio.java diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 031d9ceafa8..d1217b0ba93 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2694,8 +2694,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, FLAG_SET_CMDLINE(uintx, MaxHeapSize, (uintx)long_max_heap_size); // Xmaxf } else if (match_option(option, "-Xmaxf", &tail)) { - int maxf = (int)(atof(tail) * 100); - if (maxf < 0 || maxf > 100) { + char* err; + int maxf = (int)(strtod(tail, &err) * 100); + if (*err != '\0' || maxf < 0 || maxf > 100) { jio_fprintf(defaultStream::error_stream(), "Bad max heap free percentage size: %s\n", option->optionString); @@ -2705,8 +2706,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, } // Xminf } else if (match_option(option, "-Xminf", &tail)) { - int minf = (int)(atof(tail) * 100); - if (minf < 0 || minf > 100) { + char* err; + int minf = (int)(strtod(tail, &err) * 100); + if (*err != '\0' || minf < 0 || minf > 100) { jio_fprintf(defaultStream::error_stream(), "Bad min heap free percentage size: %s\n", option->optionString); diff --git a/hotspot/test/gc/arguments/TestHeapFreeRatio.java b/hotspot/test/gc/arguments/TestHeapFreeRatio.java new file mode 100644 index 00000000000..11e259df038 --- /dev/null +++ b/hotspot/test/gc/arguments/TestHeapFreeRatio.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestHeapFreeRatio + * @key gc + * @bug 8025661 + * @summary Test parsing of -Xminf and -Xmaxf + * @library /testlibrary + * @run main/othervm TestHeapFreeRatio + */ + +import com.oracle.java.testlibrary.*; + +public class TestHeapFreeRatio { + + enum Validation { + VALID, + MIN_INVALID, + MAX_INVALID, + COMBINATION_INVALID + } + + private static void testMinMaxFreeRatio(String min, String max, Validation type) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xminf" + min, + "-Xmaxf" + max, + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + switch (type) { + case VALID: + output.shouldNotContain("Error"); + output.shouldHaveExitValue(0); + break; + case MIN_INVALID: + output.shouldContain("Bad min heap free percentage size: -Xminf" + min); + output.shouldContain("Error"); + output.shouldHaveExitValue(1); + break; + case MAX_INVALID: + output.shouldContain("Bad max heap free percentage size: -Xmaxf" + max); + output.shouldContain("Error"); + output.shouldHaveExitValue(1); + break; + case COMBINATION_INVALID: + output.shouldContain("must be less than or equal to MaxHeapFreeRatio"); + output.shouldContain("Error"); + output.shouldHaveExitValue(1); + break; + default: + throw new IllegalStateException("Must specify expected validation type"); + } + + System.out.println(output.getOutput()); + } + + public static void main(String args[]) throws Exception { + testMinMaxFreeRatio( "0.1", "0.5", Validation.VALID); + testMinMaxFreeRatio( ".1", ".5", Validation.VALID); + testMinMaxFreeRatio( "0.5", "0.5", Validation.VALID); + + testMinMaxFreeRatio("-0.1", "0.5", Validation.MIN_INVALID); + testMinMaxFreeRatio( "1.1", "0.5", Validation.MIN_INVALID); + testMinMaxFreeRatio("=0.1", "0.5", Validation.MIN_INVALID); + testMinMaxFreeRatio("0.1f", "0.5", Validation.MIN_INVALID); + testMinMaxFreeRatio( + "INVALID", "0.5", Validation.MIN_INVALID); + testMinMaxFreeRatio( + "2147483647", "0.5", Validation.MIN_INVALID); + + testMinMaxFreeRatio( "0.1", "-0.5", Validation.MAX_INVALID); + testMinMaxFreeRatio( "0.1", "1.5", Validation.MAX_INVALID); + testMinMaxFreeRatio( "0.1", "0.5f", Validation.MAX_INVALID); + testMinMaxFreeRatio( "0.1", "=0.5", Validation.MAX_INVALID); + testMinMaxFreeRatio( + "0.1", "INVALID", Validation.MAX_INVALID); + testMinMaxFreeRatio( + "0.1", "2147483647", Validation.MAX_INVALID); + + testMinMaxFreeRatio( "0.5", "0.1", Validation.COMBINATION_INVALID); + testMinMaxFreeRatio( ".5", ".10", Validation.COMBINATION_INVALID); + testMinMaxFreeRatio("0.12","0.100", Validation.COMBINATION_INVALID); + } +} From 09523f25836fcad9a19ce383a9c5277b4db9a920 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Oct 2013 12:38:09 -0700 Subject: [PATCH 077/152] 8026368: doclint does not report empty tags when tag closed implicitly Reviewed-by: darcy --- .../com/sun/tools/doclint/Checker.java | 34 ++++++++++++++----- .../test/tools/doclint/HtmlAttrsTest.java | 2 +- .../test/tools/doclint/HtmlAttrsTest.out | 2 +- langtools/test/tools/doclint/tidy/BadEnd.out | 5 ++- .../tools/doclint/tidy/TrimmingEmptyTag.java | 9 +++-- .../tools/doclint/tidy/TrimmingEmptyTag.out | 8 ++++- 6 files changed, 45 insertions(+), 15 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index bc4b86b0a09..d3ed9c26bde 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -213,6 +213,7 @@ public class Checker extends DocTreePathScanner { public Void visitDocComment(DocCommentTree tree, Void ignore) { super.visitDocComment(tree, ignore); for (TagStackItem tsi: tagStack) { + warnIfEmpty(tsi, null); if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT && tsi.tag.endKind == HtmlTag.EndKind.REQUIRED) { StartElementTree t = (StartElementTree) tsi.tree; @@ -270,7 +271,6 @@ public class Checker extends DocTreePathScanner { @Override public Void visitStartElement(StartElementTree tree, Void ignore) { - markEnclosingTag(Flag.HAS_ELEMENT); final Name treeName = tree.getName(); final HtmlTag t = HtmlTag.get(treeName); if (t == null) { @@ -279,7 +279,10 @@ public class Checker extends DocTreePathScanner { boolean done = false; for (TagStackItem tsi: tagStack) { if (tsi.tag.accepts(t)) { - while (tagStack.peek() != tsi) tagStack.pop(); + while (tagStack.peek() != tsi) { + warnIfEmpty(tagStack.peek(), null); + tagStack.pop(); + } done = true; break; } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL) { @@ -288,9 +291,13 @@ public class Checker extends DocTreePathScanner { } } if (!done && HtmlTag.BODY.accepts(t)) { - tagStack.clear(); + while (!tagStack.isEmpty()) { + warnIfEmpty(tagStack.peek(), null); + tagStack.pop(); + } } + markEnclosingTag(Flag.HAS_ELEMENT); checkStructure(tree, t); // tag specific checks @@ -447,12 +454,7 @@ public class Checker extends DocTreePathScanner { "dc.no.summary.or.caption.for.table"); } } - if (t.flags.contains(HtmlTag.Flag.EXPECT_CONTENT) - && !top.flags.contains(Flag.HAS_TEXT) - && !top.flags.contains(Flag.HAS_ELEMENT) - && !top.flags.contains(Flag.HAS_INLINE_TAG)) { - env.messages.warning(HTML, tree, "dc.tag.empty", treeName); - } + warnIfEmpty(top, tree); tagStack.pop(); done = true; break; @@ -485,6 +487,20 @@ public class Checker extends DocTreePathScanner { return super.visitEndElement(tree, ignore); } + + void warnIfEmpty(TagStackItem tsi, DocTree endTree) { + if (tsi.tag != null && tsi.tree instanceof StartElementTree) { + if (tsi.tag.flags.contains(HtmlTag.Flag.EXPECT_CONTENT) + && !tsi.flags.contains(Flag.HAS_TEXT) + && !tsi.flags.contains(Flag.HAS_ELEMENT) + && !tsi.flags.contains(Flag.HAS_INLINE_TAG)) { + DocTree tree = (endTree != null) ? endTree : tsi.tree; + Name treeName = ((StartElementTree) tsi.tree).getName(); + env.messages.warning(HTML, tree, "dc.tag.empty", treeName); + } + } + } + // // diff --git a/langtools/test/tools/doclint/HtmlAttrsTest.java b/langtools/test/tools/doclint/HtmlAttrsTest.java index 66d6445418e..fc6e39077e9 100644 --- a/langtools/test/tools/doclint/HtmlAttrsTest.java +++ b/langtools/test/tools/doclint/HtmlAttrsTest.java @@ -10,7 +10,7 @@ /** */ public class HtmlAttrsTest { /** - *

    + *

    text

    */ public void unknown() { } diff --git a/langtools/test/tools/doclint/HtmlAttrsTest.out b/langtools/test/tools/doclint/HtmlAttrsTest.out index ec735e2a778..9cc90ce09d8 100644 --- a/langtools/test/tools/doclint/HtmlAttrsTest.out +++ b/langtools/test/tools/doclint/HtmlAttrsTest.out @@ -1,5 +1,5 @@ HtmlAttrsTest.java:13: error: unknown attribute: xyz - *

    + *

    text

    ^ HtmlAttrsTest.java:18: warning: attribute obsolete: name * alt diff --git a/langtools/test/tools/doclint/tidy/BadEnd.out b/langtools/test/tools/doclint/tidy/BadEnd.out index 1be10681cdd..991479cf630 100644 --- a/langtools/test/tools/doclint/tidy/BadEnd.out +++ b/langtools/test/tools/doclint/tidy/BadEnd.out @@ -1,6 +1,9 @@ BadEnd.java:14: warning: nested tag not allowed: * text ^ +BadEnd.java:14: warning: empty tag + * text + ^ BadEnd.java:14: error: element not closed: code * text ^ @@ -14,4 +17,4 @@ BadEnd.java:13: error: element not closed: a * text ^ 4 errors -1 warning +2 warnings diff --git a/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java b/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java index e795d62fc19..29a2069e6ef 100644 --- a/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java +++ b/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8026368 * @summary Add new doclint package * @library .. * @build DocLintTester @@ -26,4 +26,9 @@ *
      *
      */ -public class TrimmingEmptyTag { } +public class TrimmingEmptyTag { + /**

      */ + public void implicitParaEnd_endOfComment() { } + /**

      • text
      */ + public void implicitParaEnd_nextBlockTag() { } +} diff --git a/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out b/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out index 68ca2908812..f352a2595b8 100644 --- a/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out +++ b/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out @@ -43,4 +43,10 @@ TrimmingEmptyTag.java:25: warning: empty tag TrimmingEmptyTag.java:26: warning: empty
        tag *
          ^ -15 warnings +TrimmingEmptyTag.java:30: warning: empty

          tag + /**

          */ + ^ +TrimmingEmptyTag.java:32: warning: empty

          tag + /**

          • text
          */ + ^ +17 warnings From da21af58f4811285f7050691d51fe32600c0e5f8 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Mon, 14 Oct 2013 22:11:09 +0200 Subject: [PATCH 078/152] 8014016: javac is too late detecting invalid annotation usage Adding new queue to Annotate for validation tasks, performing annotation validation during enter Reviewed-by: jjg, emc, jfranck --- .../sun/tools/javac/code/TypeAnnotations.java | 18 ++ .../com/sun/tools/javac/comp/Annotate.java | 8 + .../com/sun/tools/javac/comp/Attr.java | 67 +++++-- .../com/sun/tools/javac/comp/Check.java | 48 +++-- .../com/sun/tools/javac/comp/MemberEnter.java | 35 +++- .../failures/CantAnnotateStaticClass.out | 4 +- .../GenerateFunctionalInterface.java | 38 ++++ .../GenerateSuperInterfaceProcessor.java | 60 +++++++ .../Processor.java | 170 ++++++++++++++++++ .../StopOnInapplicableAnnotations/Source.java | 59 ++++++ 10 files changed, 470 insertions(+), 37 deletions(-) create mode 100644 langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateFunctionalInterface.java create mode 100644 langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateSuperInterfaceProcessor.java create mode 100644 langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java create mode 100644 langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Source.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 61f77ff0608..5d5b74d6993 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -50,6 +50,7 @@ import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate.Annotator; +import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.tree.JCTree; @@ -95,6 +96,7 @@ public class TypeAnnotations { final Names names; final Symtab syms; final Annotate annotate; + final Attr attr; private final boolean typeAnnoAsserts; protected TypeAnnotations(Context context) { @@ -103,6 +105,7 @@ public class TypeAnnotations { log = Log.instance(context); syms = Symtab.instance(context); annotate = Annotate.instance(context); + attr = Attr.instance(context); Options options = Options.instance(context); typeAnnoAsserts = options.isSet("TypeAnnotationAsserts"); } @@ -131,6 +134,21 @@ public class TypeAnnotations { } ); } + public void validateTypeAnnotationsSignatures(final Env env, final JCClassDecl tree) { + annotate.validate(new Annotator() { //validate annotations + @Override + public void enterAnnotation() { + JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); + + try { + attr.validateTypeAnnotations(tree, true); + } finally { + log.useSource(oldSource); + } + } + } ); + } + /** * This version only visits types in bodies, that is, field initializers, * top-level blocks, and method bodies, and should be called from Attr. diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index 461b7948262..e241739a46d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -92,6 +92,7 @@ public class Annotate { ListBuffer typesQ = new ListBuffer(); ListBuffer repeatedQ = new ListBuffer(); ListBuffer afterRepeatedQ = new ListBuffer(); + ListBuffer validateQ = new ListBuffer(); public void earlier(Annotator a) { q.prepend(a); @@ -113,6 +114,10 @@ public class Annotate { afterRepeatedQ.append(a); } + public void validate(Annotator a) { + validateQ.append(a); + } + /** Called when the Enter phase starts. */ public void enterStart() { enterCount++; @@ -140,6 +145,9 @@ public class Annotate { while (afterRepeatedQ.nonEmpty()) { afterRepeatedQ.next().enterAnnotation(); } + while (validateQ.nonEmpty()) { + validateQ.next().enterAnnotation(); + } } finally { enterCount--; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 090ea9c3039..92e061600ce 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -965,12 +965,6 @@ public class Attr extends JCTree.Visitor { chk.validateAnnotationType(tree.restype); // ensure that annotation method does not clash with members of Object/Annotation chk.validateAnnotationMethod(tree.pos(), m); - - if (tree.defaultValue != null) { - // if default value is an annotation, check it is a well-formed - // annotation value (e.g. no duplicate values, no missing values, etc.) - chk.validateAnnotationTree(tree.defaultValue); - } } for (List l = tree.thrown; l.nonEmpty(); l = l.tail) @@ -1032,7 +1026,6 @@ public class Attr extends JCTree.Visitor { localEnv.info.scope.leave(); result = tree.type = m.type; - chk.validateAnnotations(tree.mods.annotations, m); } finally { chk.setLint(prevLint); @@ -1090,7 +1083,6 @@ public class Attr extends JCTree.Visitor { } } result = tree.type = v.type; - chk.validateAnnotations(tree.mods.annotations, v); } finally { chk.setLint(prevLint); @@ -4155,7 +4147,6 @@ public class Attr extends JCTree.Visitor { JCCompilationUnit toplevel = env.toplevel; try { annotate.flush(); - chk.validateAnnotations(toplevel.packageAnnotations, toplevel.packge); } catch (CompletionFailure ex) { chk.completionError(toplevel.pos(), ex); } @@ -4240,6 +4231,7 @@ public class Attr extends JCTree.Visitor { chk.checkDeprecatedAnnotation(env.tree.pos(), c); chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c); + chk.checkFunctionalInterface((JCClassDecl) env.tree, c); } finally { env.info.returnResult = prevReturnRes; log.useSource(prev); @@ -4258,9 +4250,6 @@ public class Attr extends JCTree.Visitor { JCClassDecl tree = (JCClassDecl)env.tree; Assert.check(c == tree.sym); - // Validate annotations - chk.validateAnnotations(tree.mods.annotations, c); - // Validate type parameters, supertype and interfaces. attribStats(tree.typarams, env); if (!c.isAnonymous()) { @@ -4361,7 +4350,7 @@ public class Attr extends JCTree.Visitor { typeAnnotations.organizeTypeAnnotationsBodies(tree); // Check type annotations applicability rules - validateTypeAnnotations(tree); + validateTypeAnnotations(tree, false); } } // where @@ -4436,14 +4425,19 @@ public class Attr extends JCTree.Visitor { return types.capture(type); } - private void validateTypeAnnotations(JCTree tree) { - tree.accept(typeAnnotationsValidator); + public void validateTypeAnnotations(JCTree tree, boolean sigOnly) { + tree.accept(new TypeAnnotationsValidator(sigOnly)); } //where - private final JCTree.Visitor typeAnnotationsValidator = new TreeScanner() { + private final class TypeAnnotationsValidator extends TreeScanner { + private final boolean sigOnly; private boolean checkAllAnnotations = false; + public TypeAnnotationsValidator(boolean sigOnly) { + this.sigOnly = sigOnly; + } + public void visitAnnotation(JCAnnotation tree) { if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) { chk.validateTypeAnnotation(tree, false); @@ -4467,12 +4461,26 @@ public class Attr extends JCTree.Visitor { if (tree.restype != null && tree.restype.type != null) { validateAnnotatedType(tree.restype, tree.restype.type); } - super.visitMethodDef(tree); + if (sigOnly) { + scan(tree.mods); + scan(tree.restype); + scan(tree.typarams); + scan(tree.recvparam); + scan(tree.params); + scan(tree.thrown); + } else { + scan(tree.defaultValue); + scan(tree.body); + } } public void visitVarDef(final JCVariableDecl tree) { if (tree.sym != null && tree.sym.type != null) validateAnnotatedType(tree, tree.sym.type); - super.visitVarDef(tree); + scan(tree.mods); + scan(tree.vartype); + if (!sigOnly) { + scan(tree.init); + } } public void visitTypeCast(JCTypeCast tree) { if (tree.clazz != null && tree.clazz.type != null) @@ -4509,6 +4517,29 @@ public class Attr extends JCTree.Visitor { super.visitNewArray(tree); } + @Override + public void visitClassDef(JCClassDecl tree) { + if (sigOnly) { + scan(tree.mods); + scan(tree.typarams); + scan(tree.extending); + scan(tree.implementing); + } + for (JCTree member : tree.defs) { + if (member.hasTag(Tag.CLASSDEF)) { + continue; + } + scan(member); + } + } + + @Override + public void visitBlock(JCBlock tree) { + if (!sigOnly) { + scan(tree.stats); + } + } + /* I would want to model this after * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess) * and override visitSelect and visitTypeApply. diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index e86ecc90ea6..d7290748eac 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -30,6 +30,7 @@ import java.util.*; import javax.tools.JavaFileManager; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -1951,7 +1952,7 @@ public class Check { * for errors. * @param m The overriding method. */ - void checkOverride(JCTree tree, MethodSymbol m) { + void checkOverride(JCMethodDecl tree, MethodSymbol m) { ClassSymbol origin = (ClassSymbol)m.owner; if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { @@ -1967,6 +1968,17 @@ public class Check { checkOverride(tree, t2, origin, m); } } + + if (m.attribute(syms.overrideType.tsym) != null && !isOverrider(m)) { + DiagnosticPosition pos = tree.pos(); + for (JCAnnotation a : tree.getModifiers().annotations) { + if (a.annotationType.type.tsym == syms.overrideType.tsym) { + pos = a.pos(); + break; + } + } + log.error(pos, "method.does.not.override.superclass"); + } } void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) { @@ -2725,20 +2737,11 @@ public class Check { if (!annotationApplicable(a, s)) log.error(a.pos(), "annotation.type.not.applicable"); - if (a.annotationType.type.tsym == syms.overrideType.tsym) { - if (!isOverrider(s)) - log.error(a.pos(), "method.does.not.override.superclass"); - } - if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) { if (s.kind != TYP) { log.error(a.pos(), "bad.functional.intf.anno"); - } else { - try { - types.findDescriptorSymbol((TypeSymbol)s); - } catch (Types.FunctionDescriptorLookupError ex) { - log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic()); - } + } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) { + log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s)); } } } @@ -2953,7 +2956,7 @@ public class Check { return false; } - /** Is the annotation applicable to type annotations? */ + /** Is the annotation applicable to types? */ protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { Attribute.Compound atTarget = a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); @@ -3507,4 +3510,23 @@ public class Check { public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) { return new ConversionWarner(pos, "unchecked.assign", found, expected); } + + public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) { + Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym); + + if (functionalType != null) { + try { + types.findDescriptorSymbol((TypeSymbol)cs); + } catch (Types.FunctionDescriptorLookupError ex) { + DiagnosticPosition pos = tree.pos(); + for (JCAnnotation a : tree.getModifiers().annotations) { + if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) { + pos = a.pos(); + break; + } + } + log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic()); + } + } + } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index e30398ecbe5..29e210a1b87 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -871,6 +871,18 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } }); + + annotate.validate(new Annotate.Annotator() { //validate annotations + @Override + public void enterAnnotation() { + JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); + try { + chk.validateAnnotations(annotations, s); + } finally { + log.useSource(prev); + } + } + }); } /** @@ -951,6 +963,19 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } }); + annotate.validate(new Annotate.Annotator() { //validate annotations + @Override + public void enterAnnotation() { + JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); + try { + // if default value is an annotation, check it is a well-formed + // annotation value (e.g. no duplicate values, no missing values, etc.) + chk.validateAnnotationTree(defaultValue); + } finally { + log.useSource(prev); + } + } + }); } /** Enter a default value for an attribute method. */ @@ -1157,15 +1182,17 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (wasFirst) { try { while (halfcompleted.nonEmpty()) { - finish(halfcompleted.next()); + Env toFinish = halfcompleted.next(); + finish(toFinish); + if (allowTypeAnnos) { + typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); + typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); + } } } finally { isFirst = true; } } - if (allowTypeAnnos) { - typeAnnotations.organizeTypeAnnotationsSignatures(env, tree); - } } /* diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out index 3223539ca24..585cc0aec4b 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out @@ -1,10 +1,10 @@ CantAnnotateStaticClass.java:22:20: compiler.err.cant.annotate.static.class CantAnnotateStaticClass.java:23:13: compiler.err.cant.annotate.static.class CantAnnotateStaticClass.java:24:29: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:26:29: compiler.err.cant.annotate.static.class CantAnnotateStaticClass.java:29:26: compiler.err.cant.annotate.static.class CantAnnotateStaticClass.java:30:9: compiler.err.cant.annotate.static.class CantAnnotateStaticClass.java:31:35: compiler.err.cant.annotate.static.class +CantAnnotateStaticClass.java:26:29: compiler.err.cant.annotate.static.class - compiler.note.unchecked.filename: CantAnnotateStaticClass.java - compiler.note.unchecked.recompile -7 errors +7 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateFunctionalInterface.java b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateFunctionalInterface.java new file mode 100644 index 00000000000..c88be30808f --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateFunctionalInterface.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8014016 + * @summary Ensure that an annotation processor can generate a super-interface + * which will make the current interface functional + * @build GenerateSuperInterfaceProcessor + * @compile -processor GenerateSuperInterfaceProcessor GenerateFunctionalInterface.java + */ + +import java.lang.FunctionalInterface; + +@FunctionalInterface +@Generate(fileName="SuperInterface.java", content="interface SuperInterface { public void run(); }") +interface GenerateFunctionalInterface extends SuperInterface { +} diff --git a/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateSuperInterfaceProcessor.java b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateSuperInterfaceProcessor.java new file mode 100644 index 00000000000..994c844a178 --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/GenerateSuperInterfaceProcessor.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.javac.util.Assert; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; + +@SupportedAnnotationTypes("*") +public class GenerateSuperInterfaceProcessor extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (Element el : roundEnv.getElementsAnnotatedWith(Generate.class)) { + Generate g = el.getAnnotation(Generate.class); + + Assert.checkNonNull(g); + + try (OutputStream out = + processingEnv.getFiler().createSourceFile(g.fileName()).openOutputStream()) { + out.write(g.content().getBytes()); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + return false; + } + +} + +@interface Generate { + String fileName(); + String content(); +} \ No newline at end of file diff --git a/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java new file mode 100644 index 00000000000..be90d983d0f --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.Assert; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; + +@SupportedAnnotationTypes("*") +public class Processor extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + throw new IllegalStateException("Should not be invoked."); + } + + public static void main(String... args) throws IOException, URISyntaxException { + if (args.length != 1) throw new IllegalStateException("Must provide class name!"); + String testContent = null; + List sourcePath = new ArrayList<>(); + for (String sourcePaths : System.getProperty("test.src.path").split(":")) { + sourcePath.add(new File(sourcePaths)); + } + JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); + for (File sp : sourcePath) { + File inp = new File(sp, args[0]); + + if (inp.canRead()) { + testContent = fm.getRegularFile(inp).getCharContent(true).toString(); + } + } + if (testContent == null) throw new IllegalStateException(); + DiagnosticListener devNull = new DiagnosticListener() { + @Override public void report(Diagnostic diagnostic) { } + }; + JavaFileObject testFile = new TestFO(new URI("mem://" + args[0]), testContent); + JavacTask task = JavacTool.create().getTask(null, + new TestFM(fm), + devNull, + Arrays.asList("-Xjcov"), + null, + Arrays.asList(testFile)); + final Trees trees = Trees.instance(task); + final CompilationUnitTree cut = task.parse().iterator().next(); + task.analyze(); + + final List annotations = new ArrayList<>(); + + new TreeScanner() { + @Override + public Void visitAnnotation(AnnotationTree node, Void p) { + int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node); + + Assert.check(endPos >= 0); + + annotations.add(new int[] {(int) trees.getSourcePositions().getStartPosition(cut, node), endPos}); + return super.visitAnnotation(node, p); + } + }.scan(cut.getTypeDecls().get(0), null); + + Collections.sort(annotations, new Comparator() { + @Override public int compare(int[] o1, int[] o2) { + return o2[0] - o1[0]; + } + }); + + for (final int[] annotation : annotations) { + StringBuilder updatedContent = new StringBuilder(); + int last = testContent.length(); + + for (int[] toRemove : annotations) { + if (toRemove == annotation) continue; + updatedContent.insert(0, testContent.substring(toRemove[1], last)); + last = toRemove[0]; + } + + updatedContent.insert(0, testContent.substring(0, last)); + + JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]), updatedContent.toString()); + JavacTask testTask = JavacTool.create().getTask(null, + new TestFM(fm), + devNull, + Arrays.asList("-processor", "Processor"), + null, + Arrays.asList(updatedFile)); + + try { + testTask.analyze(); + } catch (Throwable e) { + System.out.println("error while processing:"); + System.out.println(updatedContent); + throw e; + } + } + } + + private static final class TestFO extends SimpleJavaFileObject { + private final String content; + public TestFO(URI uri, String content) { + super(uri, Kind.SOURCE); + this.content = content; + } + + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return content; + } + + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return true; + } + } + + private static final class TestFM extends ForwardingJavaFileManager { + + public TestFM(JavaFileManager fileManager) { + super(fileManager); + } + + @Override + public boolean isSameFile(FileObject a, FileObject b) { + return a.equals(b); + } + + } +} \ No newline at end of file diff --git a/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Source.java b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Source.java new file mode 100644 index 00000000000..4b86712673d --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Source.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8014016 + * @summary Verify that annotation processors do not get invalid annotations + * @build Processor + * @run main Processor Source.java + */ + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@OnMethod +@OnField +class Class<@OnType @OnMethod @OnField T extends @OnType @OnMethod @OnField CharSequence & @OnType @OnMethod @OnField Runnable> extends @OnType @OnMethod @OnField Object { + + @OnType + @OnTypeUse + @OnField + private void testMethod(@OnType @OnField @OnMethod int i) { } + + @OnType + @OnMethod + private java.lang.@OnType @OnMethod @OnField String testField; +} + +@Target(ElementType.TYPE) +@interface OnType {} + +@Target(ElementType.METHOD) +@interface OnMethod {} + +@Target(ElementType.TYPE_USE) +@interface OnTypeUse {} + +@Target(ElementType.FIELD) +@interface OnField {} From fc85ec65d856047bb2ebb3d41fe508032793e860 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Oct 2013 16:28:44 -0700 Subject: [PATCH 079/152] 8026371: "tidy" issues in langtools/src/**/*.html files Reviewed-by: darcy --- .../{package.html => package-info.java} | 110 +++++++++--------- .../com/sun/tools/classfile/package-info.java | 37 ++++++ .../com/sun/tools/classfile/package.html | 12 -- .../formats/html/markup/package-info.java | 35 ++++++ .../doclets/formats/html/markup/package.html | 32 ----- .../doclets/formats/html/package-info.java | 40 +++++++ .../tools/doclets/formats/html/package.html | 38 ------ .../toolkit/builders/package-info.java | 41 +++++++ .../internal/toolkit/builders/package.html | 43 ------- .../internal/toolkit/package-info.java | 57 +++++++++ .../doclets/internal/toolkit/package.html | 55 --------- .../toolkit/taglets/package-info.java | 52 +++++++++ .../internal/toolkit/taglets/package.html | 54 --------- .../toolkit/util/links/package-info.java | 35 ++++++ .../internal/toolkit/util/links/package.html | 33 ------ .../internal/toolkit/util/package-info.java | 36 ++++++ .../internal/toolkit/util/package.html | 38 ------ .../com/sun/tools/doclets/package-info.java | 36 ++++++ .../com/sun/tools/doclets/package.html | 34 ------ .../com/sun/tools/javap/package-info.java | 35 ++++++ .../classes/com/sun/tools/javap/package.html | 10 -- .../classes/javax/lang/model/overview.html | 8 +- .../share/classes/javax/tools/overview.html | 31 +++++ 23 files changed, 492 insertions(+), 410 deletions(-) rename langtools/src/share/classes/com/sun/javadoc/{package.html => package-info.java} (68%) create mode 100644 langtools/src/share/classes/com/sun/tools/classfile/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/classfile/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/doclets/package.html create mode 100644 langtools/src/share/classes/com/sun/tools/javap/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/tools/javap/package.html diff --git a/langtools/src/share/classes/com/sun/javadoc/package.html b/langtools/src/share/classes/com/sun/javadoc/package-info.java similarity index 68% rename from langtools/src/share/classes/com/sun/javadoc/package.html rename to langtools/src/share/classes/com/sun/javadoc/package-info.java index b44dd461906..15a0fd1af36 100644 --- a/langtools/src/share/classes/com/sun/javadoc/package.html +++ b/langtools/src/share/classes/com/sun/javadoc/package-info.java @@ -1,54 +1,49 @@ - - -Doclet API Package - - - +/* + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/** The Doclet API (also called the Javadoc API) provides a mechanism -for clients to inspect the source-level structure of programs and +for clients to inspect the source-level structure of programs and libraries, including javadoc comments embedded in the source. This is useful for documentation, program checking, automatic code generation and many other tools.

          -Doclets are invoked by javadoc and use this API to write out +Doclets are invoked by javadoc and use this API to write out program information to files. For example, the standard doclet is called by default and writes out documentation to HTML files.

          -The invocation is defined by the abstract {@link com.sun.javadoc.Doclet} class +The invocation is defined by the abstract {@link com.sun.javadoc.Doclet} class -- the entry point is the {@link com.sun.javadoc.Doclet#start(RootDoc) start} method:

               public static boolean start(RootDoc root)
           
          The {@link com.sun.javadoc.RootDoc} instance holds the root of the program structure -information. From this root all other program structure -information can be extracted. +information. From this root all other program structure +information can be extracted.

          @@ -56,28 +51,28 @@ information can be extracted. When calling javadoc, you pass in package names and source file names -- -these are called the specified packages and classes. -You also pass in Javadoc options; the access control Javadoc options -(-public, -protected, -package, -and -private) filter program elements, producing a +these are called the specified packages and classes. +You also pass in Javadoc options; the access control Javadoc options +(-public, -protected, -package, +and -private) filter program elements, producing a result set, called the included set, or "documented" set. -(The unfiltered set is also available through +(The unfiltered set is also available through {@link com.sun.javadoc.PackageDoc#allClasses(boolean) allClasses(false)}.)

          Throughout this API, the term class is normally a -shorthand for "class or interface", as in: {@link com.sun.javadoc.ClassDoc}, +shorthand for "class or interface", as in: {@link com.sun.javadoc.ClassDoc}, {@link com.sun.javadoc.PackageDoc#allClasses() allClasses()}, and {@link com.sun.javadoc.PackageDoc#findClass(String) findClass(String)}. -In only a couple of other places, it means "class, as opposed to interface", +In only a couple of other places, it means "class, as opposed to interface", as in: {@link com.sun.javadoc.Doc#isClass()}. In the second sense, this API calls out four kinds of classes: -{@linkplain com.sun.javadoc.Doc#isOrdinaryClass() ordinary classes}, +{@linkplain com.sun.javadoc.Doc#isOrdinaryClass() ordinary classes}, {@linkplain com.sun.javadoc.Doc#isEnum() enums}, -{@linkplain com.sun.javadoc.Doc#isError() errors} and +{@linkplain com.sun.javadoc.Doc#isError() errors} and {@linkplain com.sun.javadoc.Doc#isException() exceptions}. -Throughout the API, the detailed description of each program element +Throughout the API, the detailed description of each program element describes explicitly which meaning is being used.

          @@ -89,8 +84,8 @@ name has no package name, such as String.

          Example

          - -The following is an example doclet that + +The following is an example doclet that displays information in the @param tags of the processed classes:
          @@ -117,17 +112,17 @@ public class ListParams extends Doclet
                               + " - " + params[j].parameterComment());
                       }
                   }
          -    }        
          +    }
           }
           
          -Interfaces and methods from the Javadoc API are marked in -red. -{@link com.sun.javadoc.Doclet Doclet} is an abstract class that specifies -the invocation interface for doclets, -{@link com.sun.javadoc.Doclet Doclet} holds class or interface information, +Interfaces and methods from the Javadoc API are marked in +red. +{@link com.sun.javadoc.Doclet Doclet} is an abstract class that specifies +the invocation interface for doclets, +{@link com.sun.javadoc.Doclet Doclet} holds class or interface information, {@link com.sun.javadoc.ExecutableMemberDoc} is a -superinterface of {@link com.sun.javadoc.MethodDoc} and -{@link com.sun.javadoc.ConstructorDoc}, +superinterface of {@link com.sun.javadoc.MethodDoc} and +{@link com.sun.javadoc.ConstructorDoc}, and {@link com.sun.javadoc.ParamTag} holds information from "@param" tags.

          @@ -148,5 +143,6 @@ producing output like: @see com.sun.javadoc.Doclet @see com.sun.javadoc.RootDoc - - +*/ +@jdk.Exported +package com.sun.javadoc; diff --git a/langtools/src/share/classes/com/sun/tools/classfile/package-info.java b/langtools/src/share/classes/com/sun/tools/classfile/package-info.java new file mode 100644 index 00000000000..588ae3b88b4 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/classfile/package-info.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + A minimalist library to read and write class files into objects closely + based on the corresponding definitions in + The Java™ Virtual Machine Specification (JVMS). + +

          This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.classfile; diff --git a/langtools/src/share/classes/com/sun/tools/classfile/package.html b/langtools/src/share/classes/com/sun/tools/classfile/package.html deleted file mode 100644 index 765dfb1acbe..00000000000 --- a/langtools/src/share/classes/com/sun/tools/classfile/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - A minimalist library to read and write class files into objects closely - based on the corresponding definitions in - The Java™ Virtual Machine Specification (JVMS). - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package-info.java new file mode 100644 index 00000000000..3503e95467a --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + This package contains classes that write HTML markup tags. + +

          This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. + */ +@jdk.Exported(false) +package com.sun.tools.doclets.formats.html.markup; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package.html b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package.html deleted file mode 100644 index 7030fae017a..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/package.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -com.sun.tools.doclets.formats.html.markup package - - This package contains classes that write HTML markup tags. - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/package-info.java new file mode 100644 index 00000000000..e4d51f6793a --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/package-info.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + This is the default doclet provided with JDK that produces Javadoc's + default HTML-formatted API output. For more documentation + on this doclet, please refer to the link below. + + @see + http://www.java.sun.com/javadoc/standard-doclet.html + +

          This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets.formats.html; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/package.html b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/package.html deleted file mode 100644 index ef2bcd224af..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/package.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - -com.sun.tools.doclets.formats.html package - - - This is the default doclet provided with JDK that produces Javadoc's - default HTML-formatted API output. For more documentation - on this doclet, please refer to the link below. - - @see - http://www.java.sun.com/javadoc/standard-doclet.html - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package-info.java new file mode 100644 index 00000000000..a5e2db3e137 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package-info.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + This doclet-independent package has a set of classes and + interfaces that are the building blocks for doclets. They + define the basic structure of doclets and make doclet + writing much easier because they provide the content generation + code to be shared among different doclets. Builders only provide + the structure and content of API documentation. + They will not provide any style markup. + +

          This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets.internal.toolkit.builders; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package.html b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package.html deleted file mode 100644 index ab9d7ada62b..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - -com.sun.tools.doclets.internal.toolkit.builders package - - - This doclet-independent package has a set of classes and - interfaces that are the building blocks for doclets. They - define the basic structure of doclets and make doclet - writing much easier because they provide the content generation - code to be shared among different doclets. Builders only provide - the structure and content of API documentation. - They will not provide any style markup. -

          - This code is not part of an API. - It is implementation that is subject to change. - Do not use it as an API. - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package-info.java new file mode 100644 index 00000000000..5e3f61f4cde --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package-info.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + Contains the base classes that make up a doclet. Doclets that reuse + the functionality provided by the toolkit should have the following + characteristics: +

            +
          • + The main driver class should extend + {@link com.sun.tools.doclets.internal.toolkit.AbstractDoclet}. +
          • +
          • + The doclet configuration class should extend + {@link com.sun.tools.doclets.internal.toolkit.Configuration}. +
          • +
          • + The doclet should have a writer factory that implements + {@link com.sun.tools.doclets.internal.toolkit.WriterFactory}. + This class constructs writers that write doclet specific output. +
          • +
          • + The doclet should have a taglet writer that extends + {@link com.sun.tools.doclets.internal.toolkit.taglets.TagletWriter}. + This writer determines how to output each given tag. +
          • +
          + +

          This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets.internal.toolkit; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package.html b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package.html deleted file mode 100644 index 65d21d5b8b1..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/package.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - -com.sun.tools.doclets.internal.toolkit package - - - - Contains the base classes that make up a doclet. Doclets that reuse - the functionality provided by the toolkit should have the following - characteristics: -

            -
          • - The main driver class should extend - {@link com.sun.tools.doclets.internal.toolkit.AbstractDoclet}. -
          • -
          • - The doclet configuration class should extend - {@link com.sun.tools.doclets.internal.toolkit.Configuration}. -
          • -
          • - The doclet should have a writer factory that implements - {@link com.sun.tools.doclets.internal.toolkit.WriterFactory}. - This class constructs writers that write doclet specific output. -
          • -
          • - The doclet should have a taglet writer that extends - {@link com.sun.tools.doclets.internal.toolkit.taglets.TagletWriter}. - This writer determines how to output each given tag. -
          • - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package-info.java new file mode 100644 index 00000000000..cb7d6b6f5ef --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package-info.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + This package has classes used to generate Javadoc tag documentation. + Doclets no longer have to implement its own version of standard tags + such as @param and @throws. This is the single, doclet + implementation of each standard tag that is shared by all + doclets. Each doclet must have a taglet writer that takes a taglet + as input and writes doclet-dependent output. The taglet itself will + do the tag processing. For example, suppose we are outputing + @throws tags. The taglet would: +
              +
            • Retrieve the list of throws tags to be documented. +
            • Replace {@inheritDoc} with the appropriate documentation. +
            • Add throws documentation for exceptions that are declared in + the signature of the method but + not documented with the throws tags. +
            + After doing the steps above, the taglet would pass the information to + the taglet writer for writing. The taglets are essentially builders for + tags. + +

            This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets.internal.toolkit.taglets; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package.html b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package.html deleted file mode 100644 index 14034c0e0b4..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - -com.sun.tools.doclets.internal.toolkit.taglets package - - - This package has classes used to generate Javadoc tag documentation. - Doclets no longer have to implement its own version of standard tags - such as @param and @throws. This is the single, doclet - implementation of each standard tag that is shared by all - doclets. Each doclet must have a taglet writer that takes a taglet - as input and writes doclet-dependent output. The taglet itself will - do the tag processing. For example, suppose we are outputing - @throws tags. The taglet would: -

              -
            • Retrieve the list of throws tags to be documented. -
            • Replace {@inheritDoc} with the appropriate documentation. -
            • Add throws documentation for exceptions that are declared in - the signature of the method but - not documented with the throws tags. -
            - After doing the steps above, the taglet would pass the information to - the taglet writer for writing. The taglets are essentially builders for - tags. -

            - This code is not part of an API. - It is implementation that is subject to change. - Do not use it as an API. - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package-info.java new file mode 100644 index 00000000000..7244b533d23 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + Provides a factory for constructing links. + +

            This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets.internal.toolkit.util.links; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package.html b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package.html deleted file mode 100644 index b58ed337142..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - -com.sun.tools.doclets.interal.toolkit.util.links package - - - Provides a factory for constructing links. - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package-info.java new file mode 100644 index 00000000000..39f37a302a4 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + This package has utility classes that perform common services required + for API documentation generation. + +

            This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets.internal.toolkit.util; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package.html b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package.html deleted file mode 100644 index 3b46f51c608..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - -com.sun.tools.doclets.internal.toolkit.util package - - - This package has utility classes that perform common services required - for API documentation generation. -

            - This code is not part of an API. - It is implementation that is subject to change. - Do not use it as an API. - - diff --git a/langtools/src/share/classes/com/sun/tools/doclets/package-info.java b/langtools/src/share/classes/com/sun/tools/doclets/package-info.java new file mode 100644 index 00000000000..6df5c2bb845 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + As of JDK version 1.5, replaced by + {@code com.sun.tools.doclets.internal.toolkit.util}. + +

            This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.doclets; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/package.html b/langtools/src/share/classes/com/sun/tools/doclets/package.html deleted file mode 100644 index bc5abe1920d..00000000000 --- a/langtools/src/share/classes/com/sun/tools/doclets/package.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - -com.sun.tools/doclets package - - - As of JDK version 1.5, replaced by - {@code com.sun.tools.doclets.internal.toolkit.util}. - - diff --git a/langtools/src/share/classes/com/sun/tools/javap/package-info.java b/langtools/src/share/classes/com/sun/tools/javap/package-info.java new file mode 100644 index 00000000000..aa2de0038da --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javap/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + Classes to dump class files in text format. + +

            This is NOT part of any supported API. + If you write code that depends on this, you do so at your own risk. + This code and its internal interfaces are subject to change or + deletion without notice. +*/ +@jdk.Exported(false) +package com.sun.tools.javap; diff --git a/langtools/src/share/classes/com/sun/tools/javap/package.html b/langtools/src/share/classes/com/sun/tools/javap/package.html deleted file mode 100644 index 60374f29756..00000000000 --- a/langtools/src/share/classes/com/sun/tools/javap/package.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Classes to dump class files in text format. - - diff --git a/langtools/src/share/classes/javax/lang/model/overview.html b/langtools/src/share/classes/javax/lang/model/overview.html index c0e98332641..9eabdcf7ba0 100644 --- a/langtools/src/share/classes/javax/lang/model/overview.html +++ b/langtools/src/share/classes/javax/lang/model/overview.html @@ -1,8 +1,6 @@ - - - + + +javax.lang.model diff --git a/langtools/src/share/classes/javax/tools/overview.html b/langtools/src/share/classes/javax/tools/overview.html index 1c831df0c5f..883b8d4aa16 100644 --- a/langtools/src/share/classes/javax/tools/overview.html +++ b/langtools/src/share/classes/javax/tools/overview.html @@ -1,3 +1,33 @@ + + + + + +javax.tools +

            @@ -21,3 +51,4 @@ abstraction.

          + From 72e730826383d14bf5229b9f8e85929832a2c93d Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Mon, 14 Oct 2013 21:52:42 -0400 Subject: [PATCH 080/152] 8026299: invokespecial gets ICCE when it should get AME Reviewed-by: ccheung, coleenp --- .../src/share/vm/interpreter/linkResolver.cpp | 39 ++++++++++--------- .../src/share/vm/interpreter/linkResolver.hpp | 2 +- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 9cebf9115ed..6705feb6ccc 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -454,7 +454,7 @@ void LinkResolver::resolve_method_statically(methodHandle& resolved_method, Klas Symbol* method_name = vmSymbols::invoke_name(); Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass(THREAD, pool->pool_holder()); - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); return; } @@ -476,22 +476,34 @@ void LinkResolver::resolve_method_statically(methodHandle& resolved_method, Klas if (code == Bytecodes::_invokeinterface) { resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); + } else if (code == Bytecodes::_invokevirtual) { + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); } else { - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); } } void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, - KlassHandle current_klass, bool check_access, TRAPS) { + KlassHandle current_klass, bool check_access, + bool require_methodref, TRAPS) { Handle nested_exception; - // 1. lookup method in resolved klass and its super klasses + // 1. check if methodref required, that resolved_klass is not interfacemethodref + if (require_methodref && resolved_klass->is_interface()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", + resolved_klass()->external_name()); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + + // 2. lookup method in resolved klass and its super klasses lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); if (resolved_method.is_null()) { // not found in the class hierarchy - // 2. lookup method in all the interfaces implemented by the resolved klass + // 3. lookup method in all the interfaces implemented by the resolved klass lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); if (resolved_method.is_null()) { @@ -505,7 +517,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res } if (resolved_method.is_null()) { - // 3. method lookup failed + // 4. method lookup failed ResourceMark rm(THREAD); THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), Method::name_and_sig_as_C_string(resolved_klass(), @@ -515,15 +527,6 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res } } - // 4. check if klass is not interface - if (resolved_klass->is_interface() && resolved_method->is_abstract()) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", - resolved_klass()->external_name()); - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - // 5. check if method is concrete if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { ResourceMark rm(THREAD); @@ -833,7 +836,7 @@ void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); // check if static @@ -867,7 +870,7 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method // and the selected method is recalculated relative to the direct superclass // superinterface.method, which explicitly does not check shadowing - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); // check if method name is , that it is found in same klass as static type if (resolved_method->name() == vmSymbols::object_initializer_name() && @@ -1013,7 +1016,7 @@ void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { // normal method resolution - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); diff --git a/hotspot/src/share/vm/interpreter/linkResolver.hpp b/hotspot/src/share/vm/interpreter/linkResolver.hpp index 55a4ddf4592..339cb92ba29 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp @@ -136,7 +136,7 @@ class LinkResolver: AllStatic { static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS); static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); From 75969430ac91d2f24c4b9d12aee678b42c3a043a Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Mon, 14 Oct 2013 22:07:29 -0700 Subject: [PATCH 081/152] 8015092: SchemaFactory cannot parse schema if whitespace added within patterns in Selector XPath expression Reviewed-by: lancea, alanb --- .../com/sun/org/apache/xerces/internal/impl/xpath/XPath.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/XPath.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/XPath.java index 90d6491d568..eb652a89441 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/XPath.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/XPath.java @@ -1422,7 +1422,7 @@ public class XPath { } ch = data.charAt(currentOffset); } while (ch == ' ' || ch == 0x0A || ch == 0x09 || ch == 0x0D); - if (currentOffset == endOffset || ch == '|') { + if (currentOffset == endOffset || ch == '|' || ch == '/') { addToken(tokens, XPath.Tokens.EXPRTOKEN_PERIOD); starIsMultiplyOperator = true; break; From 31b34ce39c670c391bf7d432550d0d2b2aeefe2f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Oct 2013 22:34:37 -0700 Subject: [PATCH 082/152] 8025693: recent javadoc changes cause com/sun/javadoc/testLinkOption/TestLinkOption.java to fail Reviewed-by: darcy --- .../com/sun/tools/javadoc/ClassDocImpl.java | 6 +- .../test/tools/javadoc/8025693/Test.java | 91 +++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javadoc/8025693/Test.java diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java index 160ccbceb10..9ea169d0866 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java @@ -619,8 +619,10 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc { Names names = tsym.name.table.names; List methods = List.nil(); for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { - if (e.sym != null && - e.sym.kind == Kinds.MTH && e.sym.name != names.init) { + if (e.sym != null + && e.sym.kind == Kinds.MTH + && e.sym.name != names.init + && e.sym.name != names.clinit) { MethodSymbol s = (MethodSymbol)e.sym; if (!filter || env.shouldDocument(s)) { methods = methods.prepend(env.getMethodDoc(s)); diff --git a/langtools/test/tools/javadoc/8025693/Test.java b/langtools/test/tools/javadoc/8025693/Test.java new file mode 100644 index 00000000000..7dc60950987 --- /dev/null +++ b/langtools/test/tools/javadoc/8025693/Test.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025693 + * @summary javadoc should ignore methods found in classes on classpath + */ + +import java.io.*; + +public class Test { + public static void main(String[] args) throws Exception { + new Test().run(); + } + + final File baseFile = new File("src/Base.java"); + final String baseText = + "package p;\n" + + "public class Base { static { } }\n"; + + final File srcFile = new File("src/C.java"); + final String srcText = + "package p;\n" + + "/** comment */\n" + + "public abstract class C extends Base { }\n"; + + void run() throws Exception { + File classesDir = new File("classes"); + classesDir.mkdirs(); + writeFile(baseFile, baseText); + String[] javacArgs = { + "-d", classesDir.getPath(), + baseFile.getPath() + }; + com.sun.tools.javac.Main.compile(javacArgs); + + writeFile(srcFile, srcText); + String[] args = { + "-d", "api", + "-classpath", classesDir.getPath(), + "-package", "p", + srcFile.getPath() + }; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + PrintStream prev = System.err; + System.setErr(ps); + try { + int rc = com.sun.tools.javadoc.Main.execute(args); + } finally { + System.err.flush(); + System.setErr(prev); + } + String out = baos.toString(); + System.out.println(out); + + String errorMessage = "java.lang.IllegalArgumentException: "; + if (out.contains(errorMessage)) + throw new Exception("error message found: " + errorMessage); + } + + void writeFile(File file, String body) throws IOException { + file.getParentFile().mkdirs(); + try (FileWriter out = new FileWriter(file)) { + out.write(body); + } + } +} + From 0837163643a4bb3e6d62a45ea226e0a6b65d6093 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Oct 2013 23:07:43 -0700 Subject: [PATCH 083/152] 8025998: Missing LV table in lambda bodies Reviewed-by: vromero --- .../com/sun/tools/javac/code/Flags.java | 8 +- .../com/sun/tools/javac/comp/Flow.java | 4 +- .../sun/tools/javac/comp/LambdaToMethod.java | 12 +- .../classes/com/sun/tools/javac/jvm/Gen.java | 4 +- .../javac/lambda/LocalVariableTable.java | 206 ++++++++++++++++++ 5 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/LocalVariableTable.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 2f59cfab7fd..3b1c40e2c92 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -270,6 +270,11 @@ public class Flags { */ public static final long POTENTIALLY_AMBIGUOUS = 1L<<48; + /** + * Flag that marks a synthetic method body for a lambda expression + */ + public static final long LAMBDA_METHOD = 1L<<49; + /** Modifier masks. */ public static final int @@ -378,7 +383,8 @@ public class Flags { NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), BAD_OVERRIDE(Flags.BAD_OVERRIDE), SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), - THROWS(Flags.THROWS); + THROWS(Flags.THROWS), + LAMBDA_METHOD(Flags.LAMBDA_METHOD); Flag(long flag) { this.value = flag; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 8c69c814965..8237d77a22b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1718,9 +1718,9 @@ public class Flow { if (tree.body == null) { return; } - /* MemberEnter can generate synthetic methods, ignore them + /* Ignore synthetic methods, except for translated lambda methods. */ - if ((tree.sym.flags() & SYNTHETIC) != 0) { + if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) { return; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index e56aa535706..3329b78ff1b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -30,6 +30,7 @@ import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol; @@ -1755,7 +1756,7 @@ public class LambdaToMethod extends TreeTranslator { ((VarSymbol)ret).pos = ((VarSymbol)sym).pos; break; case CAPTURED_VAR: - ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) { + ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { //keep mapping with original captured symbol @@ -1763,6 +1764,13 @@ public class LambdaToMethod extends TreeTranslator { } }; break; + case LOCAL_VAR: + ret = new VarSymbol(FINAL, name, types.erasure(sym.type), translatedSym); + break; + case PARAM: + ret = new VarSymbol(FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym); + ((VarSymbol) ret).adr = ((VarSymbol) sym).adr; + break; default: ret = makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym); } @@ -1845,7 +1853,7 @@ public class LambdaToMethod extends TreeTranslator { // If instance access isn't needed, make it static. // Interface instance methods must be default methods. // Lambda methods are private synthetic. - translatedSym.flags_field = SYNTHETIC | + translatedSym.flags_field = SYNTHETIC | LAMBDA_METHOD | PRIVATE | (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index b48b727090f..34e61a011ee 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -2892,7 +2892,8 @@ public class Gen extends JCTree.Visitor { @Override public void visitMethodDef(JCMethodDecl tree) { - if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0) { + if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0 + && (tree.sym.flags() & LAMBDA_METHOD) == 0) { return; } if (tree.name.equals(names.clinit)) { @@ -2906,6 +2907,7 @@ public class Gen extends JCTree.Visitor { return; } currentMethod = tree.sym; + super.visitMethodDef(tree); } diff --git a/langtools/test/tools/javac/lambda/LocalVariableTable.java b/langtools/test/tools/javac/lambda/LocalVariableTable.java new file mode 100644 index 00000000000..a829d702eb8 --- /dev/null +++ b/langtools/test/tools/javac/lambda/LocalVariableTable.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025998 + * @summary Missing LV table in lambda bodies + * @compile -g LocalVariableTable.java + * @run main LocalVariableTable + */ + +import java.lang.annotation.*; +import java.util.*; +import com.sun.tools.classfile.*; + +/* + * The test checks that a LocalVariableTable attribute is generated for the + * method bodies representing lambda expressions, and checks that the expected + * set of entries is found in the attribute. + * + * Since the bug was about missing entries in the LVT, not malformed entries, + * the test is not intended to be a detailed test of the contents of each + * LocalVariableTable entry: it is assumed that if a entry is present, it + * will have the correct contents. + * + * The test looks for test cases represented by nested classes whose + * name begins with "Lambda". Each such class contains a lambda expression + * that will mapped into a lambda method, and because the test is compiled + * with -g, these methods should have a LocalVariableTable. The set of + * expected names in the LVT is provided in an annotation on the class for + * the test case. + */ +public class LocalVariableTable { + public static void main(String... args) throws Exception { + new LocalVariableTable().run(); + } + + void run() throws Exception { + // the declared classes are returned in an unspecified order, + // so for neatness, sort them by name before processing them + Class[] classes = getClass().getDeclaredClasses(); + Arrays.sort(classes, (c1, c2) -> c1.getName().compareTo(c2.getName())); + + for (Class c : classes) { + if (c.getSimpleName().startsWith("Lambda")) + check(c); + } + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + /** Check an individual test case. */ + void check(Class c) throws Exception { + System.err.println("Checking " + c.getSimpleName()); + + Expect expect = c.getAnnotation(Expect.class); + if (expect == null) { + error("@Expect not found for class " + c.getSimpleName()); + return; + } + + ClassFile cf = ClassFile.read(getClass().getResource(c.getName() + ".class").openStream()); + Method m = getLambdaMethod(cf); + if (m == null) { + error("lambda method not found"); + return; + } + + Code_attribute code = (Code_attribute) m.attributes.get(Attribute.Code); + if (code == null) { + error("Code attribute not found"); + return; + } + + LocalVariableTable_attribute lvt = + (LocalVariableTable_attribute) code.attributes.get(Attribute.LocalVariableTable); + if (lvt == null) { + error("LocalVariableTable attribute not found"); + return; + } + + Set foundNames = new LinkedHashSet<>(); + for (LocalVariableTable_attribute.Entry e: lvt.local_variable_table) { + foundNames.add(cf.constant_pool.getUTF8Value(e.name_index)); + } + + Set expectNames = new LinkedHashSet<>(Arrays.asList(expect.value())); + if (!foundNames.equals(expectNames)) { + Set foundOnly = new LinkedHashSet<>(foundNames); + foundOnly.removeAll(expectNames); + for (String s: foundOnly) + error("Unexpected name found: " + s); + Set expectOnly = new LinkedHashSet<>(expectNames); + expectOnly.removeAll(foundNames); + for (String s: expectOnly) + error("Expected name not found: " + s); + } + } + + /** Get a method whose name begins "lambda$...". */ + Method getLambdaMethod(ClassFile cf) throws ConstantPoolException { + for (Method m: cf.methods) { + if (m.getName(cf.constant_pool).startsWith("lambda$")) + return m; + } + return null; + } + + /** Report an error. */ + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; + + /** + * Annotation used to provide the set of names expected in the LVT attribute. + */ + @Retention(RetentionPolicy.RUNTIME) + @interface Expect { + String[] value(); + } + + /** Functional interface with nullary method. */ + interface Run0 { + public void run(); + } + + /** Functional interface with 1-ary method. */ + interface Run1 { + public void run(int a0); + } + + /** Functional interface with 2-ary method. */ + interface Run2 { + public void run(int a0, int a1); + } + + /* + * ---------- Test cases --------------------------------------------------- + */ + + @Expect({ "x" }) + static class Lambda_Args0_Local1 { + Run0 r = () -> { int x = 0; }; + } + + @Expect({ "x", "this" }) + static class Lambda_Args0_Local1_this { + int v; + Run0 r = () -> { int x = v; }; + } + + @Expect({ "a" }) + static class Lambda_Args1_Local0 { + Run1 r = (a) -> { }; + } + + @Expect({ "a", "x" }) + static class Lambda_Args1_Local1 { + Run1 r = (a) -> { int x = a; }; + } + + @Expect({ "a", "x" }) + static class Lambda_Args1_Local1_Captured1 { + void m() { + int v = 0; + Run1 r = (a) -> { int x = a + v; }; + } + } + + @Expect({ "a1", "a2", "x1", "x2", "this" }) + static class Lambda_Args2_Local2_Captured2_this { + int v; + void m() { + int v1 = 0; + int v2 = 0; + Run2 r = (a1, a2) -> { + int x1 = a1 + v1 + v; + int x2 = a2 + v2 + v; + }; + } + } +} + From fa38a2edcaf20bd23f8a7d752b00c1eda1ee6a29 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 15 Oct 2013 11:18:42 +0200 Subject: [PATCH 084/152] 8026186: gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java Compilation failed After a method rename in JDK-8014905 the mentioned test did not compile any more. Fix the uses of the affected method. Reviewed-by: jwilhelm, mgerdin, jmasa --- .../serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java | 2 +- .../com/oracle/java/testlibrary/JDKToolLauncher.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java index 37d7b709be7..37d7c5d2c70 100644 --- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java +++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java @@ -59,7 +59,7 @@ public class JMapHProfLargeHeapTest { // If we are on MacOSX, test if JMap tool is signed, otherwise return // since test will fail with privilege error. if (Platform.isOSX()) { - String jmapToolPath = JDKToolFinder.getCurrentJDKTool("jmap"); + String jmapToolPath = JDKToolFinder.getTestJDKTool("jmap"); ProcessBuilder codesignProcessBuilder = new ProcessBuilder( "codesign", "-v", jmapToolPath); Process codesignProcess = codesignProcessBuilder.start(); diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java index 29df4a776e6..c318ee35571 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java @@ -56,7 +56,7 @@ public class JDKToolLauncher { if (useCompilerJDK) { executable = JDKToolFinder.getJDKTool(tool); } else { - executable = JDKToolFinder.getCurrentJDKTool(tool); + executable = JDKToolFinder.getTestJDKTool(tool); } vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs())); } From 908dd5463926d2a500543cc0eabc8241610280f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 15 Oct 2013 11:38:47 +0200 Subject: [PATCH 085/152] 8023158: hotspot/test/gc/7168848/HumongousAlloc.java fails 14 full gcs, expect 0 full gcs Reviewed-by: brutisso, tschatzl --- hotspot/test/TEST.groups | 2 +- hotspot/test/gc/7168848/HumongousAlloc.java | 74 ------------------ .../gc/g1/TestHumongousAllocInitialMark.java | 75 +++++++++++++++++++ 3 files changed, 76 insertions(+), 75 deletions(-) delete mode 100644 hotspot/test/gc/7168848/HumongousAlloc.java create mode 100644 hotspot/test/gc/g1/TestHumongousAllocInitialMark.java diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 2778ebf8df9..638a5c9160d 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -124,7 +124,7 @@ needs_compact3 = \ compiler/whitebox/IsMethodCompilableTest.java \ gc/6581734/Test6581734.java \ gc/7072527/TestFullGCCount.java \ - gc/7168848/HumongousAlloc.java \ + gc/g1/TestHumongousAllocInitialMark.java \ gc/arguments/TestG1HeapRegionSize.java \ gc/metaspace/TestMetaspaceMemoryPool.java \ runtime/InternalApi/ThreadCpuTimesDeadlock.java \ diff --git a/hotspot/test/gc/7168848/HumongousAlloc.java b/hotspot/test/gc/7168848/HumongousAlloc.java deleted file mode 100644 index 7ac6074bd67..00000000000 --- a/hotspot/test/gc/7168848/HumongousAlloc.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test Humongous.java - * @bug 7168848 - * @summary G1: humongous object allocations should initiate marking cycles when necessary - * @run main/othervm -Xms100m -Xmx100m -XX:+PrintGC -XX:G1HeapRegionSize=1m -XX:+UseG1GC HumongousAlloc - * - */ -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.util.List; - -public class HumongousAlloc { - - public static byte[] dummy; - private static int sleepFreq = 40; - private static int sleepTime = 1000; - private static double size = 0.75; - private static int iterations = 50; - private static int MB = 1024 * 1024; - - public static void allocate(int size, int sleepTime, int sleepFreq) throws InterruptedException { - System.out.println("Will allocate objects of size: " + size - + " bytes and sleep for " + sleepTime - + " ms after every " + sleepFreq + "th allocation."); - int count = 0; - while (count < iterations) { - for (int i = 0; i < sleepFreq; i++) { - dummy = new byte[size - 16]; - } - Thread.sleep(sleepTime); - count++; - } - } - - public static void main(String[] args) throws InterruptedException { - allocate((int) (size * MB), sleepTime, sleepFreq); - List collectors = ManagementFactory.getGarbageCollectorMXBeans(); - for (GarbageCollectorMXBean collector : collectors) { - if (collector.getName().contains("G1 Old")) { - long count = collector.getCollectionCount(); - if (count > 0) { - throw new RuntimeException("Failed: FullGCs should not have happened. The number of FullGC run is " + count); - } - else { - System.out.println("Passed."); - } - } - } - } -} - diff --git a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java new file mode 100644 index 00000000000..468ad423f37 --- /dev/null +++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestHumongousAllocInitialMark + * @bug 7168848 + * @summary G1: humongous object allocations should initiate marking cycles when necessary + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.*; + +public class TestHumongousAllocInitialMark { + private static final int heapSize = 200; // MB + private static final int heapRegionSize = 1; // MB + private static final int initiatingHeapOccupancyPercent = 50; // % + + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UseG1GC", + "-Xms" + heapSize + "m", + "-Xmx" + heapSize + "m", + "-XX:G1HeapRegionSize=" + heapRegionSize + "m", + "-XX:InitiatingHeapOccupancyPercent=" + initiatingHeapOccupancyPercent, + "-XX:+PrintGC", + HumongousObjectAllocator.class.getName()); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("GC pause (G1 Humongous Allocation) (young) (initial-mark)"); + output.shouldNotContain("Full GC"); + output.shouldHaveExitValue(0); + } + + static class HumongousObjectAllocator { + private static byte[] dummy; + + public static void main(String [] args) throws Exception { + // Make object size 75% of region size + final int humongousObjectSize = + (int)(heapRegionSize * 1024 * 1024 * 0.75); + + // Number of objects to allocate to go above IHOP + final int humongousObjectAllocations = + (int)((heapSize * initiatingHeapOccupancyPercent / 100.0) / heapRegionSize) + 1; + + // Allocate + for (int i = 1; i <= humongousObjectAllocations; i++) { + System.out.println("Allocating humongous object " + i + "/" + humongousObjectAllocations + + " of size " + humongousObjectSize + " bytes"); + dummy = new byte[humongousObjectSize]; + } + } + } +} + From b6426924cf2dbcaf171288c5f249c0cb53accc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 15 Oct 2013 11:42:50 +0200 Subject: [PATCH 086/152] 8024632: Description of InitialSurvivorRatio flag in globals.hpp is incorrect Reviewed-by: brutisso, tschatzl, kmo, tamao --- hotspot/src/share/vm/runtime/globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index de814472a8c..5d395732681 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2175,7 +2175,7 @@ class CommandLineFlags { "Minimum ratio of young generation/survivor space size") \ \ product(uintx, InitialSurvivorRatio, 8, \ - "Initial ratio of eden/survivor space size") \ + "Initial ratio of young generation/survivor space size") \ \ product(uintx, BaseFootPrintEstimate, 256*M, \ "Estimate of footprint other than Java Heap") \ From c6e227a3e60be7aa7ffde394cbf66651fa75e599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 15 Oct 2013 11:44:47 +0200 Subject: [PATCH 087/152] 8024634: gc/startup_warnings tests can fail due to unrelated warnings Reviewed-by: brutisso, jwilhelm, tamao --- hotspot/test/gc/startup_warnings/TestCMS.java | 2 +- hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java | 2 +- hotspot/test/gc/startup_warnings/TestG1.java | 2 +- hotspot/test/gc/startup_warnings/TestParNewCMS.java | 2 +- hotspot/test/gc/startup_warnings/TestParallelGC.java | 2 +- .../test/gc/startup_warnings/TestParallelScavengeSerialOld.java | 2 +- hotspot/test/gc/startup_warnings/TestSerialGC.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hotspot/test/gc/startup_warnings/TestCMS.java b/hotspot/test/gc/startup_warnings/TestCMS.java index 22a0719576a..93bb56311e2 100644 --- a/hotspot/test/gc/startup_warnings/TestCMS.java +++ b/hotspot/test/gc/startup_warnings/TestCMS.java @@ -38,7 +38,7 @@ public class TestCMS { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java b/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java index f2180904eba..0d329fbe57e 100644 --- a/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java +++ b/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java @@ -37,7 +37,7 @@ public class TestCMSNoIncrementalMode { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:-CMSIncrementalMode", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/startup_warnings/TestG1.java b/hotspot/test/gc/startup_warnings/TestG1.java index 536612bbcea..b1dfaa427f2 100644 --- a/hotspot/test/gc/startup_warnings/TestG1.java +++ b/hotspot/test/gc/startup_warnings/TestG1.java @@ -37,7 +37,7 @@ public class TestG1 { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/startup_warnings/TestParNewCMS.java b/hotspot/test/gc/startup_warnings/TestParNewCMS.java index f74d65c662d..3f8bfb42d2f 100644 --- a/hotspot/test/gc/startup_warnings/TestParNewCMS.java +++ b/hotspot/test/gc/startup_warnings/TestParNewCMS.java @@ -38,7 +38,7 @@ public class TestParNewCMS { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/startup_warnings/TestParallelGC.java b/hotspot/test/gc/startup_warnings/TestParallelGC.java index 7a0766ebc45..e21630913c0 100644 --- a/hotspot/test/gc/startup_warnings/TestParallelGC.java +++ b/hotspot/test/gc/startup_warnings/TestParallelGC.java @@ -38,7 +38,7 @@ public class TestParallelGC { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParallelGC", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java b/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java index 27a25b23db0..5d1cbddb025 100644 --- a/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java +++ b/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java @@ -38,7 +38,7 @@ public class TestParallelScavengeSerialOld { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParallelGC", "-XX:-UseParallelOldGC", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/startup_warnings/TestSerialGC.java b/hotspot/test/gc/startup_warnings/TestSerialGC.java index d84fd5d969b..4ce1af2b440 100644 --- a/hotspot/test/gc/startup_warnings/TestSerialGC.java +++ b/hotspot/test/gc/startup_warnings/TestSerialGC.java @@ -38,7 +38,7 @@ public class TestSerialGC { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseSerialGC", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("warning"); + output.shouldNotContain("deprecated"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } From f149d47720561c27cadfc5d8715cee4b3ef428bc Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Tue, 15 Oct 2013 14:28:51 +0200 Subject: [PATCH 088/152] 8026391: The Metachunk header wastes memory Reviewed-by: coleenp, jmasa --- .../share/vm/memory/binaryTreeDictionary.cpp | 1 - .../share/vm/memory/freeBlockDictionary.cpp | 1 - hotspot/src/share/vm/memory/freeList.cpp | 1 - hotspot/src/share/vm/memory/metablock.cpp | 68 ------- hotspot/src/share/vm/memory/metablock.hpp | 101 ---------- hotspot/src/share/vm/memory/metachunk.cpp | 115 +++++++---- hotspot/src/share/vm/memory/metachunk.hpp | 183 +++++++++++------- hotspot/src/share/vm/memory/metaspace.cpp | 92 ++++----- hotspot/src/share/vm/memory/metaspace.hpp | 5 +- hotspot/src/share/vm/prims/jni.cpp | 2 + hotspot/src/share/vm/runtime/vmStructs.cpp | 2 +- 11 files changed, 231 insertions(+), 340 deletions(-) delete mode 100644 hotspot/src/share/vm/memory/metablock.cpp delete mode 100644 hotspot/src/share/vm/memory/metablock.hpp diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index bfe1d1b4ca8..30b0382992c 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -28,7 +28,6 @@ #include "memory/binaryTreeDictionary.hpp" #include "memory/freeList.hpp" #include "memory/freeBlockDictionary.hpp" -#include "memory/metablock.hpp" #include "memory/metachunk.hpp" #include "runtime/globals.hpp" #include "utilities/ostream.hpp" diff --git a/hotspot/src/share/vm/memory/freeBlockDictionary.cpp b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp index 713036ea500..7cb2b17b57b 100644 --- a/hotspot/src/share/vm/memory/freeBlockDictionary.cpp +++ b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp @@ -28,7 +28,6 @@ #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #endif // INCLUDE_ALL_GCS #include "memory/freeBlockDictionary.hpp" -#include "memory/metablock.hpp" #include "memory/metachunk.hpp" #include "runtime/thread.inline.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/memory/freeList.cpp b/hotspot/src/share/vm/memory/freeList.cpp index 385451caf81..78785e8809f 100644 --- a/hotspot/src/share/vm/memory/freeList.cpp +++ b/hotspot/src/share/vm/memory/freeList.cpp @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "memory/freeBlockDictionary.hpp" #include "memory/freeList.hpp" -#include "memory/metablock.hpp" #include "memory/metachunk.hpp" #include "memory/sharedHeap.hpp" #include "runtime/globals.hpp" diff --git a/hotspot/src/share/vm/memory/metablock.cpp b/hotspot/src/share/vm/memory/metablock.cpp deleted file mode 100644 index b6c6947e1ac..00000000000 --- a/hotspot/src/share/vm/memory/metablock.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "memory/allocation.hpp" -#include "memory/metablock.hpp" -#include "utilities/copy.hpp" -#include "utilities/debug.hpp" - -// Blocks of space for metadata are allocated out of Metachunks. -// -// Metachunk are allocated out of MetadataVirtualspaces and once -// allocated there is no explicit link between a Metachunk and -// the MetadataVirtualspaces from which it was allocated. -// -// Each SpaceManager maintains a -// list of the chunks it is using and the current chunk. The current -// chunk is the chunk from which allocations are done. Space freed in -// a chunk is placed on the free list of blocks (BlockFreelist) and -// reused from there. -// -// Future modification -// -// The Metachunk can conceivable be replaced by the Chunk in -// allocation.hpp. Note that the latter Chunk is the space for -// allocation (allocations from the chunk are out of the space in -// the Chunk after the header for the Chunk) where as Metachunks -// point to space in a VirtualSpace. To replace Metachunks with -// Chunks, change Chunks so that they can be allocated out of a VirtualSpace. -size_t Metablock::_min_block_byte_size = sizeof(Metablock); - -// New blocks returned by the Metaspace are zero initialized. -// We should fix the constructors to not assume this instead. -Metablock* Metablock::initialize(MetaWord* p, size_t word_size) { - if (p == NULL) { - return NULL; - } - - Metablock* result = (Metablock*) p; - - // Clear the memory - Copy::fill_to_aligned_words((HeapWord*)result, word_size); -#ifdef ASSERT - result->set_word_size(word_size); -#endif - return result; -} diff --git a/hotspot/src/share/vm/memory/metablock.hpp b/hotspot/src/share/vm/memory/metablock.hpp deleted file mode 100644 index fa4c6c0b445..00000000000 --- a/hotspot/src/share/vm/memory/metablock.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ -#ifndef SHARE_VM_MEMORY_METABLOCK_HPP -#define SHARE_VM_MEMORY_METABLOCK_HPP - -// Metablock are the unit of allocation from a Chunk. It is initialized -// with the size of the requested allocation. That size is overwritten -// once the allocation returns. -// -// A Metablock may be reused by its SpaceManager but are never moved between -// SpaceManagers. There is no explicit link to the Metachunk -// from which it was allocated. Metablock may be deallocated and -// put on a freelist but the space is never freed, rather -// the Metachunk it is a part of will be deallocated when it's -// associated class loader is collected. - -class Metablock VALUE_OBJ_CLASS_SPEC { - friend class VMStructs; - private: - // Used to align the allocation (see below). - union block_t { - void* _data[3]; - struct header_t { - size_t _word_size; - Metablock* _next; - Metablock* _prev; - } _header; - } _block; - static size_t _min_block_byte_size; - - typedef union block_t Block; - typedef struct header_t Header; - const Block* block() const { return &_block; } - const Block::header_t* header() const { return &(block()->_header); } - public: - - static Metablock* initialize(MetaWord* p, size_t word_size); - - // This places the body of the block at a 2 word boundary - // because every block starts on a 2 word boundary. Work out - // how to make the body on a 2 word boundary if the block - // starts on a arbitrary boundary. JJJ - - size_t word_size() const { return header()->_word_size; } - void set_word_size(size_t v) { _block._header._word_size = v; } - size_t size() const volatile { return _block._header._word_size; } - void set_size(size_t v) { _block._header._word_size = v; } - Metablock* next() const { return header()->_next; } - void set_next(Metablock* v) { _block._header._next = v; } - Metablock* prev() const { return header()->_prev; } - void set_prev(Metablock* v) { _block._header._prev = v; } - - static size_t min_block_byte_size() { return _min_block_byte_size; } - - bool is_free() { return header()->_word_size != 0; } - void clear_next() { set_next(NULL); } - void link_prev(Metablock* ptr) { set_prev(ptr); } - uintptr_t* end() { return ((uintptr_t*) this) + size(); } - bool cantCoalesce() const { return false; } - void link_next(Metablock* ptr) { set_next(ptr); } - void link_after(Metablock* ptr){ - link_next(ptr); - if (ptr != NULL) ptr->link_prev(this); - } - - // Should not be needed in a free list of Metablocks - void markNotFree() { ShouldNotReachHere(); } - - // Debug support -#ifdef ASSERT - void* prev_addr() const { return (void*)&_block._header._prev; } - void* next_addr() const { return (void*)&_block._header._next; } - void* size_addr() const { return (void*)&_block._header._word_size; } -#endif - bool verify_chunk_in_free_list(Metablock* tc) const { return true; } - bool verify_par_locked() { return true; } - - void assert_is_mangled() const {/* Don't check "\*/} -}; -#endif // SHARE_VM_MEMORY_METABLOCK_HPP diff --git a/hotspot/src/share/vm/memory/metachunk.cpp b/hotspot/src/share/vm/memory/metachunk.cpp index 0ac4ced70f4..2f9af7fe82d 100644 --- a/hotspot/src/share/vm/memory/metachunk.cpp +++ b/hotspot/src/share/vm/memory/metachunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. 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,42 +29,32 @@ #include "utilities/debug.hpp" class VirtualSpaceNode; -// -// Future modification -// -// The Metachunk can conceivable be replaced by the Chunk in -// allocation.hpp. Note that the latter Chunk is the space for -// allocation (allocations from the chunk are out of the space in -// the Chunk after the header for the Chunk) where as Metachunks -// point to space in a VirtualSpace. To replace Metachunks with -// Chunks, change Chunks so that they can be allocated out of a VirtualSpace. const size_t metadata_chunk_initialize = 0xf7f7f7f7; -size_t Metachunk::_overhead = - Chunk::aligned_overhead_size(sizeof(Metachunk)) / BytesPerWord; +size_t Metachunk::object_alignment() { + return ARENA_AMALLOC_ALIGNMENT; +} + +size_t Metachunk::overhead() { + return align_size_up(sizeof(Metachunk), object_alignment()) / BytesPerWord; +} // Metachunk methods Metachunk::Metachunk(size_t word_size, - VirtualSpaceNode* container) : - _word_size(word_size), - _bottom(NULL), - _end(NULL), + VirtualSpaceNode* container) + : Metabase(word_size), _top(NULL), - _next(NULL), - _prev(NULL), _container(container) { - _bottom = (MetaWord*)this; - _top = (MetaWord*)this + _overhead; - _end = (MetaWord*)this + word_size; + _top = initial_top(); #ifdef ASSERT - set_is_free(false); + set_is_tagged_free(false); size_t data_word_size = pointer_delta(end(), - top(), + _top, sizeof(MetaWord)); - Copy::fill_to_words((HeapWord*) top(), + Copy::fill_to_words((HeapWord*)_top, data_word_size, metadata_chunk_initialize); #endif @@ -82,22 +72,18 @@ MetaWord* Metachunk::allocate(size_t word_size) { // _bottom points to the start of the chunk including the overhead. size_t Metachunk::used_word_size() const { - return pointer_delta(_top, _bottom, sizeof(MetaWord)); + return pointer_delta(_top, bottom(), sizeof(MetaWord)); } size_t Metachunk::free_word_size() const { - return pointer_delta(_end, _top, sizeof(MetaWord)); -} - -size_t Metachunk::capacity_word_size() const { - return pointer_delta(_end, _bottom, sizeof(MetaWord)); + return pointer_delta(end(), _top, sizeof(MetaWord)); } void Metachunk::print_on(outputStream* st) const { st->print_cr("Metachunk:" " bottom " PTR_FORMAT " top " PTR_FORMAT " end " PTR_FORMAT " size " SIZE_FORMAT, - bottom(), top(), end(), word_size()); + bottom(), _top, end(), word_size()); if (Verbose) { st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT, used_word_size(), free_word_size()); @@ -109,8 +95,8 @@ void Metachunk::mangle() { // Mangle the payload of the chunk and not the links that // maintain list of chunks. HeapWord* start = (HeapWord*)(bottom() + overhead()); - size_t word_size = capacity_word_size() - overhead(); - Copy::fill_to_words(start, word_size, metadata_chunk_initialize); + size_t size = word_size() - overhead(); + Copy::fill_to_words(start, size, metadata_chunk_initialize); } #endif // PRODUCT @@ -118,9 +104,68 @@ void Metachunk::verify() { #ifdef ASSERT // Cannot walk through the blocks unless the blocks have // headers with sizes. - assert(_bottom <= _top && - _top <= _end, + assert(bottom() <= _top && + _top <= (MetaWord*)end(), "Chunk has been smashed"); #endif return; } + +/////////////// Unit tests /////////////// + +#ifndef PRODUCT + +class TestMetachunk { + public: + static void test() { + size_t size = 2 * 1024 * 1024; + void* memory = malloc(size); + assert(memory != NULL, "Failed to malloc 2MB"); + + Metachunk* metachunk = ::new (memory) Metachunk(size / BytesPerWord, NULL); + + assert(metachunk->bottom() == (MetaWord*)metachunk, "assert"); + assert(metachunk->end() == (uintptr_t*)metachunk + metachunk->size(), "assert"); + + // Check sizes + assert(metachunk->size() == metachunk->word_size(), "assert"); + assert(metachunk->word_size() == pointer_delta(metachunk->end(), metachunk->bottom(), + sizeof(MetaWord*)), "assert"); + + // Check usage + assert(metachunk->used_word_size() == metachunk->overhead(), "assert"); + assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert"); + assert(metachunk->top() == metachunk->initial_top(), "assert"); + assert(metachunk->is_empty(), "assert"); + + // Allocate + size_t alloc_size = 64; // Words + assert(is_size_aligned(alloc_size, Metachunk::object_alignment()), "assert"); + + MetaWord* mem = metachunk->allocate(alloc_size); + + // Check post alloc + assert(mem == metachunk->initial_top(), "assert"); + assert(mem + alloc_size == metachunk->top(), "assert"); + assert(metachunk->used_word_size() == metachunk->overhead() + alloc_size, "assert"); + assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert"); + assert(!metachunk->is_empty(), "assert"); + + // Clear chunk + metachunk->reset_empty(); + + // Check post clear + assert(metachunk->used_word_size() == metachunk->overhead(), "assert"); + assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert"); + assert(metachunk->top() == metachunk->initial_top(), "assert"); + assert(metachunk->is_empty(), "assert"); + + free(memory); + } +}; + +void TestMetachunk_test() { + TestMetachunk::test(); +} + +#endif diff --git a/hotspot/src/share/vm/memory/metachunk.hpp b/hotspot/src/share/vm/memory/metachunk.hpp index ff237ab5d3f..5ea8e235de6 100644 --- a/hotspot/src/share/vm/memory/metachunk.hpp +++ b/hotspot/src/share/vm/memory/metachunk.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,89 +24,44 @@ #ifndef SHARE_VM_MEMORY_METACHUNK_HPP #define SHARE_VM_MEMORY_METACHUNK_HPP -// Metachunk - Quantum of allocation from a Virtualspace -// Metachunks are reused (when freed are put on a global freelist) and -// have no permanent association to a SpaceManager. - -// +--------------+ <- end -// | | --+ ---+ -// | | | free | -// | | | | -// | | | | capacity -// | | | | -// | | <- top --+ | -// | | ---+ | -// | | | used | -// | | | | -// | | | | -// +--------------+ <- bottom ---+ ---+ +#include "memory/allocation.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" class VirtualSpaceNode; -class Metachunk VALUE_OBJ_CLASS_SPEC { - // link to support lists of chunks - Metachunk* _next; - Metachunk* _prev; - VirtualSpaceNode* _container; - - MetaWord* _bottom; - MetaWord* _end; - MetaWord* _top; +// Super class of Metablock and Metachunk to allow them to +// be put on the FreeList and in the BinaryTreeDictionary. +template +class Metabase VALUE_OBJ_CLASS_SPEC { size_t _word_size; - // Used in a guarantee() so included in the Product builds - // even through it is only for debugging. - bool _is_free; + T* _next; + T* _prev; - // Metachunks are allocated out of a MetadataVirtualSpace and - // and use some of its space to describe itself (plus alignment - // considerations). Metadata is allocated in the rest of the chunk. - // This size is the overhead of maintaining the Metachunk within - // the space. - static size_t _overhead; + protected: + Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {} public: - Metachunk(size_t word_size , VirtualSpaceNode* container); + T* next() const { return _next; } + T* prev() const { return _prev; } + void set_next(T* v) { _next = v; assert(v != this, "Boom");} + void set_prev(T* v) { _prev = v; assert(v != this, "Boom");} + void clear_next() { set_next(NULL); } + void clear_prev() { set_prev(NULL); } - // Used to add a Metachunk to a list of Metachunks - void set_next(Metachunk* v) { _next = v; assert(v != this, "Boom");} - void set_prev(Metachunk* v) { _prev = v; assert(v != this, "Boom");} - void set_container(VirtualSpaceNode* v) { _container = v; } - - MetaWord* allocate(size_t word_size); - - // Accessors - Metachunk* next() const { return _next; } - Metachunk* prev() const { return _prev; } - VirtualSpaceNode* container() const { return _container; } - MetaWord* bottom() const { return _bottom; } - MetaWord* end() const { return _end; } - MetaWord* top() const { return _top; } - size_t word_size() const { return _word_size; } size_t size() const volatile { return _word_size; } void set_size(size_t v) { _word_size = v; } - bool is_free() { return _is_free; } - void set_is_free(bool v) { _is_free = v; } - static size_t overhead() { return _overhead; } - void clear_next() { set_next(NULL); } - void link_prev(Metachunk* ptr) { set_prev(ptr); } - uintptr_t* end() { return ((uintptr_t*) this) + size(); } - bool cantCoalesce() const { return false; } - void link_next(Metachunk* ptr) { set_next(ptr); } - void link_after(Metachunk* ptr){ + + void link_next(T* ptr) { set_next(ptr); } + void link_prev(T* ptr) { set_prev(ptr); } + void link_after(T* ptr) { link_next(ptr); - if (ptr != NULL) ptr->link_prev(this); + if (ptr != NULL) ptr->link_prev((T*)this); } - // Reset top to bottom so chunk can be reused. - void reset_empty() { _top = (_bottom + _overhead); _next = NULL; _prev = NULL; } - bool is_empty() { return _top == (_bottom + _overhead); } + uintptr_t* end() const { return ((uintptr_t*) this) + size(); } - // used (has been allocated) - // free (available for future allocations) - // capacity (total size of chunk) - size_t used_word_size() const; - size_t free_word_size() const; - size_t capacity_word_size()const; + bool cantCoalesce() const { return false; } // Debug support #ifdef ASSERT @@ -114,14 +69,98 @@ class Metachunk VALUE_OBJ_CLASS_SPEC { void* next_addr() const { return (void*)&_next; } void* size_addr() const { return (void*)&_word_size; } #endif - bool verify_chunk_in_free_list(Metachunk* tc) const { return true; } + bool verify_chunk_in_free_list(T* tc) const { return true; } bool verify_par_locked() { return true; } void assert_is_mangled() const {/* Don't check "\*/} - NOT_PRODUCT(void mangle();) + bool is_free() { return true; } +}; + +// Metachunk - Quantum of allocation from a Virtualspace +// Metachunks are reused (when freed are put on a global freelist) and +// have no permanent association to a SpaceManager. + +// +--------------+ <- end --+ --+ +// | | | | +// | | | free | +// | | | | +// | | | | size | capacity +// | | | | +// | | <- top -- + | +// | | | | +// | | | used | +// | | | | +// | | | | +// +--------------+ <- bottom --+ --+ + +class Metachunk : public Metabase { + friend class TestMetachunk; + // The VirtualSpaceNode containing this chunk. + VirtualSpaceNode* _container; + + // Current allocation top. + MetaWord* _top; + + DEBUG_ONLY(bool _is_tagged_free;) + + MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } + MetaWord* top() const { return _top; } + + public: + // Metachunks are allocated out of a MetadataVirtualSpace and + // and use some of its space to describe itself (plus alignment + // considerations). Metadata is allocated in the rest of the chunk. + // This size is the overhead of maintaining the Metachunk within + // the space. + + // Alignment of each allocation in the chunks. + static size_t object_alignment(); + + // Size of the Metachunk header, including alignment. + static size_t overhead(); + + Metachunk(size_t word_size , VirtualSpaceNode* container); + + MetaWord* allocate(size_t word_size); + + VirtualSpaceNode* container() const { return _container; } + + MetaWord* bottom() const { return (MetaWord*) this; } + + // Reset top to bottom so chunk can be reused. + void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); } + bool is_empty() { return _top == initial_top(); } + + // used (has been allocated) + // free (available for future allocations) + size_t word_size() const { return size(); } + size_t used_word_size() const; + size_t free_word_size() const; + +#ifdef ASSERT + void mangle(); + bool is_tagged_free() { return _is_tagged_free; } + void set_is_tagged_free(bool v) { _is_tagged_free = v; } +#endif void print_on(outputStream* st) const; void verify(); }; + +// Metablock is the unit of allocation from a Chunk. +// +// A Metablock may be reused by its SpaceManager but are never moved between +// SpaceManagers. There is no explicit link to the Metachunk +// from which it was allocated. Metablock may be deallocated and +// put on a freelist but the space is never freed, rather +// the Metachunk it is a part of will be deallocated when it's +// associated class loader is collected. + +class Metablock : public Metabase { + friend class VMStructs; + public: + Metablock(size_t word_size) : Metabase(word_size) {} +}; + #endif // SHARE_VM_MEMORY_METACHUNK_HPP diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 832bd6dcadb..13c88adb0b2 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -30,7 +30,6 @@ #include "memory/filemap.hpp" #include "memory/freeList.hpp" #include "memory/gcLocker.hpp" -#include "memory/metablock.hpp" #include "memory/metachunk.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceShared.hpp" @@ -49,8 +48,8 @@ typedef BinaryTreeDictionary BlockTreeDictionary; typedef BinaryTreeDictionary ChunkTreeDictionary; -// Define this macro to enable slow integrity checking of -// the free chunk lists + +// Set this constant to enable slow integrity checking of the free chunk lists const bool metaspace_slow_verify = false; // Parameters for stress mode testing @@ -92,24 +91,9 @@ volatile intptr_t MetaspaceGC::_capacity_until_GC = 0; uint MetaspaceGC::_shrink_factor = 0; bool MetaspaceGC::_should_concurrent_collect = false; -// Blocks of space for metadata are allocated out of Metachunks. -// -// Metachunk are allocated out of MetadataVirtualspaces and once -// allocated there is no explicit link between a Metachunk and -// the MetadataVirtualspaces from which it was allocated. -// -// Each SpaceManager maintains a -// list of the chunks it is using and the current chunk. The current -// chunk is the chunk from which allocations are done. Space freed in -// a chunk is placed on the free list of blocks (BlockFreelist) and -// reused from there. - typedef class FreeList ChunkList; // Manages the global free lists of chunks. -// Has three lists of free chunks, and a total size and -// count that includes all three - class ChunkManager : public CHeapObj { // Free list of chunks of different sizes. @@ -119,7 +103,6 @@ class ChunkManager : public CHeapObj { // HumongousChunk ChunkList _free_chunks[NumberOfFreeLists]; - // HumongousChunk ChunkTreeDictionary _humongous_dictionary; @@ -230,7 +213,6 @@ class ChunkManager : public CHeapObj { // to the allocation of a quantum of metadata). class BlockFreelist VALUE_OBJ_CLASS_SPEC { BlockTreeDictionary* _dictionary; - static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size); // Only allocate and split from freelist if the size of the allocation // is at least 1/4th the size of the available block. @@ -258,6 +240,7 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC { void print_on(outputStream* st) const; }; +// A VirtualSpaceList node. class VirtualSpaceNode : public CHeapObj { friend class VirtualSpaceList; @@ -414,13 +397,13 @@ void VirtualSpaceNode::purge(ChunkManager* chunk_manager) { Metachunk* chunk = first_chunk(); Metachunk* invalid_chunk = (Metachunk*) top(); while (chunk < invalid_chunk ) { - assert(chunk->is_free(), "Should be marked free"); - MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); - chunk_manager->remove_chunk(chunk); - assert(chunk->next() == NULL && - chunk->prev() == NULL, - "Was not removed from its list"); - chunk = (Metachunk*) next; + assert(chunk->is_tagged_free(), "Should be tagged free"); + MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); + chunk_manager->remove_chunk(chunk); + assert(chunk->next() == NULL && + chunk->prev() == NULL, + "Was not removed from its list"); + chunk = (Metachunk*) next; } } @@ -434,7 +417,7 @@ uint VirtualSpaceNode::container_count_slow() { // Don't count the chunks on the free lists. Those are // still part of the VirtualSpaceNode but not currently // counted. - if (!chunk->is_free()) { + if (!chunk->is_tagged_free()) { count++; } chunk = (Metachunk*) next; @@ -753,14 +736,11 @@ class SpaceManager : public CHeapObj { #endif size_t get_raw_word_size(size_t word_size) { - // If only the dictionary is going to be used (i.e., no - // indexed free list), then there is a minimum size requirement. - // MinChunkSize is a placeholder for the real minimum size JJJ size_t byte_size = word_size * BytesPerWord; - size_t raw_bytes_size = MAX2(byte_size, - Metablock::min_block_byte_size()); - raw_bytes_size = ARENA_ALIGN(raw_bytes_size); + size_t raw_bytes_size = MAX2(byte_size, sizeof(Metablock)); + raw_bytes_size = align_size_up(raw_bytes_size, Metachunk::object_alignment()); + size_t raw_word_size = raw_bytes_size / BytesPerWord; assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); @@ -813,17 +793,8 @@ BlockFreelist::~BlockFreelist() { } } -Metablock* BlockFreelist::initialize_free_chunk(MetaWord* p, size_t word_size) { - Metablock* block = (Metablock*) p; - block->set_word_size(word_size); - block->set_prev(NULL); - block->set_next(NULL); - - return block; -} - void BlockFreelist::return_block(MetaWord* p, size_t word_size) { - Metablock* free_chunk = initialize_free_chunk(p, word_size); + Metablock* free_chunk = ::new (p) Metablock(word_size); if (dictionary() == NULL) { _dictionary = new BlockTreeDictionary(); } @@ -1069,7 +1040,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) { } // Chunk is being removed from the chunks free list. - dec_free_chunks_total(chunk->capacity_word_size()); + dec_free_chunks_total(chunk->word_size()); } // Walk the list of VirtualSpaceNodes and delete @@ -1760,7 +1731,7 @@ void ChunkManager::free_chunks_put(Metachunk* chunk) { chunk->set_next(free_list->head()); free_list->set_head(chunk); // chunk is being returned to the chunk free list - inc_free_chunks_total(chunk->capacity_word_size()); + inc_free_chunks_total(chunk->word_size()); slow_locked_verify(); } @@ -1822,7 +1793,7 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { } // Chunk is being removed from the chunks free list. - dec_free_chunks_total(chunk->capacity_word_size()); + dec_free_chunks_total(chunk->word_size()); // Remove it from the links to this freelist chunk->set_next(NULL); @@ -1830,7 +1801,7 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { #ifdef ASSERT // Chunk is no longer on any freelist. Setting to false make container_count_slow() // work. - chunk->set_is_free(false); + chunk->set_is_tagged_free(false); #endif chunk->container()->inc_container_count(); @@ -1962,7 +1933,7 @@ size_t SpaceManager::sum_capacity_in_chunks_in_use() const { for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { - sum += chunk->capacity_word_size(); + sum += chunk->word_size(); chunk = chunk->next(); } } @@ -2210,7 +2181,7 @@ void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) { // Capture the next link before it is changed // by the call to return_chunk_at_head(); Metachunk* next = cur->next(); - cur->set_is_free(true); + DEBUG_ONLY(cur->set_is_tagged_free(true);) list->return_chunk_at_head(cur); cur = next; } @@ -2282,7 +2253,7 @@ SpaceManager::~SpaceManager() { while (humongous_chunks != NULL) { #ifdef ASSERT - humongous_chunks->set_is_free(true); + humongous_chunks->set_is_tagged_free(true); #endif if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", @@ -2545,7 +2516,7 @@ void SpaceManager::dump(outputStream* const out) const { curr->print_on(out); curr_total += curr->word_size(); used += curr->used_word_size(); - capacity += curr->capacity_word_size(); + capacity += curr->word_size(); waste += curr->free_word_size() + curr->overhead();; } } @@ -3396,7 +3367,7 @@ void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { } -Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, +MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, bool read_only, MetaspaceObj::Type type, TRAPS) { if (HAS_PENDING_EXCEPTION) { assert(false, "Should not allocate with exception pending"); @@ -3415,10 +3386,14 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, MetaWord* result = space->allocate(word_size, NonClassType); if (result == NULL) { report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); - } else { - space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); } - return Metablock::initialize(result, word_size); + + space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); + + // Zero initialize. + Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); + + return result; } MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType; @@ -3443,7 +3418,10 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, return NULL; } - return Metablock::initialize(result, word_size); + // Zero initialize. + Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); + + return result; } void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetadataType mdtype, TRAPS) { diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 3a0f4fe60ff..974a1aac62d 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -139,7 +139,6 @@ class Metaspace : public CHeapObj { // Allocate space for metadata of type mdtype. This is space // within a Metachunk and is used by // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS) - // which returns a Metablock. MetaWord* allocate(size_t word_size, MetadataType mdtype); // Virtual Space lists for both classes and other metadata @@ -217,8 +216,8 @@ class Metaspace : public CHeapObj { size_t used_bytes_slow(MetadataType mdtype) const; size_t capacity_bytes_slow(MetadataType mdtype) const; - static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size, - bool read_only, MetaspaceObj::Type type, TRAPS); + static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size, + bool read_only, MetaspaceObj::Type type, TRAPS); void deallocate(MetaWord* ptr, size_t byte_size, bool is_class); MetaWord* expand_and_allocate(size_t size, diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index fce0715ff84..b5c271897e4 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5059,6 +5059,7 @@ void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); void TestVirtualSpace_test(); void TestMetaspaceAux_test(); +void TestMetachunk_test(); #if INCLUDE_ALL_GCS void TestG1BiasedArray_test(); #endif @@ -5070,6 +5071,7 @@ void execute_internal_vm_tests() { run_unit_test(TestReserveMemorySpecial_test()); run_unit_test(TestVirtualSpace_test()); run_unit_test(TestMetaspaceAux_test()); + run_unit_test(TestMetachunk_test()); run_unit_test(GlobalDefinitions::test_globals()); run_unit_test(GCTimerAllTest::all()); run_unit_test(arrayOopDesc::test_max_array_length()); diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 199dbac0b24..d28e34690a0 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -58,7 +58,7 @@ #include "memory/generation.hpp" #include "memory/generationSpec.hpp" #include "memory/heap.hpp" -#include "memory/metablock.hpp" +#include "memory/metachunk.hpp" #include "memory/referenceType.hpp" #include "memory/space.hpp" #include "memory/tenuredGeneration.hpp" From f323c934d7926920d5d31937d5cde67a15a7e787 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Tue, 15 Oct 2013 14:32:20 +0200 Subject: [PATCH 089/152] 8026392: Metachunks and Metablocks are using a too large alignment Reviewed-by: coleenp, jmasa --- hotspot/src/share/vm/memory/metachunk.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/memory/metachunk.cpp b/hotspot/src/share/vm/memory/metachunk.cpp index 2f9af7fe82d..81a1f8f8224 100644 --- a/hotspot/src/share/vm/memory/metachunk.cpp +++ b/hotspot/src/share/vm/memory/metachunk.cpp @@ -33,7 +33,14 @@ class VirtualSpaceNode; const size_t metadata_chunk_initialize = 0xf7f7f7f7; size_t Metachunk::object_alignment() { - return ARENA_AMALLOC_ALIGNMENT; + // Must align pointers and sizes to 8, + // so that 64 bit types get correctly aligned. + const size_t alignment = 8; + + // Make sure that the Klass alignment also agree. + STATIC_ASSERT(alignment == (size_t)KlassAlignmentInBytes); + + return alignment; } size_t Metachunk::overhead() { From 8a727caa63fe5432245e8afb587b80a2d36b086c Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Tue, 15 Oct 2013 15:57:14 +0200 Subject: [PATCH 090/152] 8026397: Fix ambiguity with array conversion, including passing JS NativeArrays in Java variable arity methods' vararg array position Reviewed-by: jlaskey, sundar --- .../dynalink/beans/SingleDynamicMethod.java | 70 ++++++++++++++--- .../jdk/internal/dynalink/support/Guards.java | 13 ++-- .../dynalink/support/messages.properties | 12 +-- .../internal/codegen/CodeGenerator.java | 6 ++ .../linker/JavaArgumentConverters.java | 19 +---- .../runtime/linker/NashornLinker.java | 76 +++++++++++++++++++ .../api/javaaccess/ArrayConversionTest.java | 44 +++++++++++ 7 files changed, 203 insertions(+), 37 deletions(-) diff --git a/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java index d15fab9966e..6b55d81f15c 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java @@ -91,6 +91,7 @@ import java.util.StringTokenizer; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.Guards; +import jdk.internal.dynalink.support.Lookup; /** * Base class for dynamic methods that dispatch to a single target Java method or constructor. Handles adaptation of the @@ -100,6 +101,9 @@ import jdk.internal.dynalink.support.Guards; * @version $Id: $ */ abstract class SingleDynamicMethod extends DynamicMethod { + + private static final MethodHandle CAN_CONVERT_TO = Lookup.findOwnStatic(MethodHandles.lookup(), "canConvertTo", boolean.class, LinkerServices.class, Class.class, Object.class); + SingleDynamicMethod(String name) { super(name); } @@ -201,23 +205,69 @@ abstract class SingleDynamicMethod extends DynamicMethod { return createConvertingInvocation(target, linkerServices, callSiteType).asVarargsCollector( callSiteLastArgType); } - if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) { - // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive); - // link immediately to a vararg-packing method handle. - return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType); + + // This method handle takes the single argument and packs it into a newly allocated single-element array. It + // will be used when the incoming argument can't be converted to the vararg array type (the "vararg packer" + // method). + final MethodHandle varArgCollectingInvocation = createConvertingInvocation(collectArguments(fixTarget, + argsLen), linkerServices, callSiteType); + + // Is call site type assignable from an array type (e.g. Object:int[], or Object[]:String[]) + final boolean isAssignableFromArray = callSiteLastArgType.isAssignableFrom(varArgType); + // Do we have a custom conversion that can potentially convert the call site type to an array? + final boolean isCustomConvertible = linkerServices.canConvert(callSiteLastArgType, varArgType); + if(!isAssignableFromArray && !isCustomConvertible) { + // Call site signature guarantees the argument can definitely not be converted to an array (i.e. it is + // primitive), and no conversion can help with it either. Link immediately to a vararg-packing method + // handle. + return varArgCollectingInvocation; } - // Call site signature makes no guarantees that the single argument in the vararg position will be - // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg - // method when it is not. - return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType), - createConvertingInvocation(fixTarget, linkerServices, callSiteType), - createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType)); + + // This method handle employs language-specific conversions to convert the last argument into an array of + // vararg type. + final MethodHandle arrayConvertingInvocation = createConvertingInvocation(MethodHandles.filterArguments( + fixTarget, fixParamsLen, linkerServices.getTypeConverter(callSiteLastArgType, varArgType)), + linkerServices, callSiteType); + + // This method handle determines whether the value can be converted to the array of vararg type using a + // language-specific conversion. + final MethodHandle canConvertArgToArray = MethodHandles.insertArguments(CAN_CONVERT_TO, 0, linkerServices, + varArgType); + + // This one adjusts the previous one for the location of the argument and the call site type. + final MethodHandle canConvertLastArgToArray = MethodHandles.dropArguments(canConvertArgToArray, 0, + MethodType.genericMethodType(fixParamsLen).parameterList()).asType(callSiteType.changeReturnType(boolean.class)); + + // This one takes the previous ones and combines them into a method handle that converts the argument into + // a vararg array when it can, otherwise falls back to the vararg packer. + final MethodHandle convertToArrayWhenPossible = MethodHandles.guardWithTest(canConvertLastArgToArray, + arrayConvertingInvocation, varArgCollectingInvocation); + + if(isAssignableFromArray) { + return MethodHandles.guardWithTest( + // Is incoming parameter already a compatible array? + Guards.isInstance(varArgType, fixParamsLen, callSiteType), + // Yes: just pass it to the method + createConvertingInvocation(fixTarget, linkerServices, callSiteType), + // No: either go through a custom conversion, or if it is not possible, go directly to the + // vararg packer. + isCustomConvertible ? convertToArrayWhenPossible : varArgCollectingInvocation); + } + + // Just do the custom conversion with fallback to the vararg packer logic. + assert isCustomConvertible; + return convertToArrayWhenPossible; } // Remaining case: more than one vararg. return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType); } + @SuppressWarnings("unused") + private static boolean canConvertTo(final LinkerServices linkerServices, Class to, Object obj) { + return obj == null ? false : linkerServices.canConvert(obj.getClass(), to); + } + /** * Creates a method handle out of the original target that will collect the varargs for the exact component type of * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs diff --git a/nashorn/src/jdk/internal/dynalink/support/Guards.java b/nashorn/src/jdk/internal/dynalink/support/Guards.java index 661cf334b5e..42aa675880a 100644 --- a/nashorn/src/jdk/internal/dynalink/support/Guards.java +++ b/nashorn/src/jdk/internal/dynalink/support/Guards.java @@ -88,6 +88,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.logging.Level; import java.util.logging.Logger; +import jdk.internal.dynalink.DynamicLinker; import jdk.internal.dynalink.linker.LinkerServices; /** @@ -115,11 +116,11 @@ public class Guards { public static MethodHandle isOfClass(Class clazz, MethodType type) { final Class declaredType = type.parameterType(0); if(clazz == declaredType) { - LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type }); + LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type, DynamicLinker.getLinkedCallSiteLocation() }); return constantTrue(type); } if(!declaredType.isAssignableFrom(clazz)) { - LOG.log(Level.WARNING, "isOfClassGuardAlwaysFalse", new Object[] { clazz.getName(), 0, type }); + LOG.log(Level.WARNING, "isOfClassGuardAlwaysFalse", new Object[] { clazz.getName(), 0, type, DynamicLinker.getLinkedCallSiteLocation() }); return constantFalse(type); } return getClassBoundArgumentTest(IS_OF_CLASS, clazz, 0, type); @@ -152,11 +153,11 @@ public class Guards { public static MethodHandle isInstance(Class clazz, int pos, MethodType type) { final Class declaredType = type.parameterType(pos); if(clazz.isAssignableFrom(declaredType)) { - LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type }); + LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type, DynamicLinker.getLinkedCallSiteLocation() }); return constantTrue(type); } if(!declaredType.isAssignableFrom(clazz)) { - LOG.log(Level.WARNING, "isInstanceGuardAlwaysFalse", new Object[] { clazz.getName(), pos, type }); + LOG.log(Level.WARNING, "isInstanceGuardAlwaysFalse", new Object[] { clazz.getName(), pos, type, DynamicLinker.getLinkedCallSiteLocation() }); return constantFalse(type); } return getClassBoundArgumentTest(IS_INSTANCE, clazz, pos, type); @@ -174,11 +175,11 @@ public class Guards { public static MethodHandle isArray(int pos, MethodType type) { final Class declaredType = type.parameterType(pos); if(declaredType.isArray()) { - LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type }); + LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type, DynamicLinker.getLinkedCallSiteLocation() }); return constantTrue(type); } if(!declaredType.isAssignableFrom(Object[].class)) { - LOG.log(Level.WARNING, "isArrayGuardAlwaysFalse", new Object[] { pos, type }); + LOG.log(Level.WARNING, "isArrayGuardAlwaysFalse", new Object[] { pos, type, DynamicLinker.getLinkedCallSiteLocation() }); return constantFalse(type); } return asType(IS_ARRAY, pos, type); diff --git a/nashorn/src/jdk/internal/dynalink/support/messages.properties b/nashorn/src/jdk/internal/dynalink/support/messages.properties index eaf1f630d09..88d59908071 100644 --- a/nashorn/src/jdk/internal/dynalink/support/messages.properties +++ b/nashorn/src/jdk/internal/dynalink/support/messages.properties @@ -76,11 +76,11 @@ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -isInstanceGuardAlwaysTrue=isInstance guard for {0} in position {1} in method type {2} will always return true -isInstanceGuardAlwaysFalse=isInstance guard for {0} in position {1} in method type {2} will always return false +isInstanceGuardAlwaysTrue=isInstance guard for {0} in position {1} in method type {2} at {3} will always return true +isInstanceGuardAlwaysFalse=isInstance guard for {0} in position {1} in method type {2} at {3} will always return false -isOfClassGuardAlwaysTrue=isOfClass guard for {0} in position {1} in method type {2} will always return true -isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} will always return false +isOfClassGuardAlwaysTrue=isOfClass guard for {0} in position {1} in method type {2} at {3} will always return true +isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} at {3} will always return false -isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} will always return true -isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} will always return false \ No newline at end of file +isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} at {2} will always return true +isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} at {2} will always return false \ No newline at end of file diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 5575c23db01..e709357221a 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -453,7 +453,13 @@ final class CodeGenerator extends NodeOperatorVisitor targetType) { - MethodHandle converter = CONVERTERS.get(targetType); - if(converter == null && targetType.isArray()) { - converter = MH.insertArguments(JSType.TO_JAVA_ARRAY.methodHandle(), 1, targetType.getComponentType()); - converter = MH.asType(converter, converter.type().changeReturnType(targetType)); - CONVERTERS.putIfAbsent(targetType, converter); - } - return converter; + return CONVERTERS.get(targetType); } @SuppressWarnings("unused") @@ -263,12 +255,9 @@ final class JavaArgumentConverters { return MH.findStatic(MethodHandles.lookup(), JavaArgumentConverters.class, name, MH.type(rtype, types)); } - private static final ConcurrentMap, MethodHandle> CONVERTERS = new ConcurrentHashMap<>(); + private static final Map, MethodHandle> CONVERTERS = new HashMap<>(); static { - CONVERTERS.put(List.class, JSType.TO_JAVA_LIST.methodHandle()); - CONVERTERS.put(Deque.class, JSType.TO_JAVA_DEQUE.methodHandle()); - CONVERTERS.put(Number.class, TO_NUMBER); CONVERTERS.put(String.class, TO_STRING); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java index 3a23b1410c5..a760c604d46 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java @@ -30,6 +30,8 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Modifier; +import java.util.Deque; +import java.util.List; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.ConversionComparator; import jdk.internal.dynalink.linker.GuardedInvocation; @@ -38,6 +40,8 @@ import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; import jdk.internal.dynalink.support.Guards; +import jdk.nashorn.internal.objects.NativeArray; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.Undefined; @@ -47,6 +51,13 @@ import jdk.nashorn.internal.runtime.Undefined; * includes {@link ScriptFunction} and its subclasses) as well as {@link Undefined}. */ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator { + private static final ClassValue ARRAY_CONVERTERS = new ClassValue() { + @Override + protected MethodHandle computeValue(Class type) { + return createArrayConverter(type); + } + }; + /** * Returns true if {@code ScriptObject} is assignable from {@code type}, or it is {@code Undefined}. */ @@ -103,6 +114,12 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp if (mh != null) { return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE); } + + GuardedInvocation inv = getArrayConverter(sourceType, targetType); + if(inv != null) { + return inv; + } + return getSamTypeConverter(sourceType, targetType); } @@ -129,6 +146,41 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp return null; } + /** + * Returns a guarded invocation that converts from a source type that is NativeArray to a Java array or List or + * Deque type. + * @param sourceType the source type (presumably NativeArray a superclass of it) + * @param targetType the target type (presumably an array type, or List or Deque) + * @return a guarded invocation that converts from the source type to the target type. null is returned if + * either the source type is neither NativeArray, nor a superclass of it, or if the target type is not an array + * type, List, or Deque. + */ + private static GuardedInvocation getArrayConverter(final Class sourceType, final Class targetType) { + final boolean isSourceTypeNativeArray = sourceType == NativeArray.class; + // If source type is more generic than ScriptFunction class, we'll need to use a guard + final boolean isSourceTypeGeneric = !isSourceTypeNativeArray && sourceType.isAssignableFrom(NativeArray.class); + + if (isSourceTypeNativeArray || isSourceTypeGeneric) { + final MethodHandle guard = isSourceTypeGeneric ? IS_NATIVE_ARRAY : null; + if(targetType.isArray()) { + return new GuardedInvocation(ARRAY_CONVERTERS.get(targetType), guard); + } + if(targetType == List.class) { + return new GuardedInvocation(JSType.TO_JAVA_LIST.methodHandle(), guard); + } + if(targetType == Deque.class) { + return new GuardedInvocation(JSType.TO_JAVA_DEQUE.methodHandle(), guard); + } + } + return null; + } + + private static MethodHandle createArrayConverter(final Class type) { + assert type.isArray(); + final MethodHandle converter = MH.insertArguments(JSType.TO_JAVA_ARRAY.methodHandle(), 1, type.getComponentType()); + return MH.asType(converter, converter.type().changeReturnType(type)); + } + private static boolean isAutoConvertibleFromFunction(final Class clazz) { return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) && JavaAdapterFactory.isAutoConvertibleFromFunction(clazz); @@ -148,7 +200,26 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp @Override public Comparison compareConversion(final Class sourceType, final Class targetType1, final Class targetType2) { + if(sourceType == NativeArray.class) { + // Prefer lists, as they're less costly to create than arrays. + if(isList(targetType1)) { + if(!isList(targetType2)) { + return Comparison.TYPE_1_BETTER; + } + } else if(isList(targetType2)) { + return Comparison.TYPE_2_BETTER; + } + // Then prefer arrays + if(targetType1.isArray()) { + if(!targetType2.isArray()) { + return Comparison.TYPE_1_BETTER; + } + } else if(targetType2.isArray()) { + return Comparison.TYPE_2_BETTER; + } + } if(ScriptObject.class.isAssignableFrom(sourceType)) { + // Prefer interfaces if(targetType1.isInterface()) { if(!targetType2.isInterface()) { return Comparison.TYPE_1_BETTER; @@ -160,7 +231,12 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp return Comparison.INDETERMINATE; } + private static boolean isList(Class clazz) { + return clazz == List.class || clazz == Deque.class; + } + private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class)); + private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class)); private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class); diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java index c6794557637..4a1d8d5dad1 100644 --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java @@ -86,11 +86,27 @@ public class ArrayConversionTest { runTest("assertBooleanArrayConversions", "[false, true, '', 'false', 0, 1, 0.4, 0.6, {}, [], [false], [true], NaN, Infinity, null, undefined]"); } + @Test + public void testArrayAmbiguity() throws ScriptException { + runTest("x", "'abc'"); + runTest("x", "['foo', 'bar']"); + } + @Test public void testListArrays() throws ScriptException { runTest("assertListArray", "[['foo', 'bar'], ['apple', 'orange']]"); } + @Test + public void testVarArgs() throws ScriptException { + // Sole NativeArray in vararg position becomes vararg array itself + runTest("assertVarArg_42_17", "[42, 17]"); + // NativeArray in vararg position becomes an argument if there are more arguments + runTest("assertVarArg_array_17", "[42], 18"); + // Only NativeArray is converted to vararg array, other objects (e.g. a function) aren't + runTest("assertVarArg_function", "function() { return 'Hello' }"); + } + private static void runTest(final String testMethodName, final String argument) throws ScriptException { e.eval("Java.type('" + ArrayConversionTest.class.getName() + "')." + testMethodName + "(" + argument + ")"); } @@ -188,4 +204,32 @@ public class ArrayConversionTest { assertEquals(Arrays.asList("foo", "bar"), array[0]); assertEquals(Arrays.asList("apple", "orange"), array[1]); } + + public static void assertVarArg_42_17(Object... args) throws ScriptException { + assertEquals(2, args.length); + assertEquals(42, ((Number)args[0]).intValue()); + assertEquals(17, ((Number)args[1]).intValue()); + } + + public static void assertVarArg_array_17(Object... args) throws ScriptException { + assertEquals(2, args.length); + e.getBindings(ScriptContext.ENGINE_SCOPE).put("arr", args[0]); + assertTrue((Boolean)e.eval("arr instanceof Array && arr.length == 1 && arr[0] == 42")); + assertEquals(18, ((Number)args[1]).intValue()); + } + + public static void assertVarArg_function(Object... args) throws ScriptException { + assertEquals(1, args.length); + e.getBindings(ScriptContext.ENGINE_SCOPE).put("fn", args[0]); + assertEquals("Hello", e.eval("fn()")); + } + + + + public static void x(String y) { + assertEquals("abc", y); + } + public static void x(String[] y) { + assertTrue(Arrays.equals(new String[] { "foo", "bar"}, y)); + } } From 52d83865b802a88e57c18441e2992060f48390df Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Tue, 15 Oct 2013 16:23:18 +0200 Subject: [PATCH 091/152] 8026180: com.sun.source.tree.NewArrayTree refers to com.sun.tools.javac.util.List Correcting import in NewArrayTree, adding test protecting againts improper types in API signatures Reviewed-by: jjg --- .../com/sun/source/tree/NewArrayTree.java | 2 +- .../javac/tree/NoPrivateTypesExported.java | 291 ++++++++++++++++++ 2 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/tree/NoPrivateTypesExported.java diff --git a/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java b/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java index f951366d630..01236e71516 100644 --- a/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java +++ b/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java @@ -25,7 +25,7 @@ package com.sun.source.tree; -import com.sun.tools.javac.util.List; +import java.util.List; /** * A tree node for an expression to create a new instance of an array. diff --git a/langtools/test/tools/javac/tree/NoPrivateTypesExported.java b/langtools/test/tools/javac/tree/NoPrivateTypesExported.java new file mode 100644 index 00000000000..c16340e5782 --- /dev/null +++ b/langtools/test/tools/javac/tree/NoPrivateTypesExported.java @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8026180 + * @summary Ensuring javax.lang.model.**, javax.tools.**, javax.annotation.processing.** + * and com.sun.source.** don't export inappropriate types. + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor NoPrivateTypesExported + * @compile -processor NoPrivateTypesExported NoPrivateTypesExported.java + */ +import java.lang.annotation.Documented; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.TypeParameterElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.IntersectionType; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; +import javax.lang.model.type.WildcardType; +import javax.lang.model.util.ElementScanner8; +import javax.lang.model.util.SimpleAnnotationValueVisitor8; +import javax.tools.Diagnostic.Kind; + +public class NoPrivateTypesExported extends JavacTestingAbstractProcessor { + + private static final String[] javaxLangModelPackages = new String[] { + "javax.lang.model", + "javax.lang.model.element", + "javax.lang.model.type", + "javax.lang.model.util", + }; + + private static final Set javaxLangModelAcceptable; + + private static final String[] javaxToolsProcessingPackages = new String[] { + "javax.annotation.processing", + "javax.tools", + }; + + private static final Set javaxToolsProcessingAcceptable; + + private static final String[] comSunSourcePackages = new String[] { + "com.sun.source.doctree", + "com.sun.source.tree", + "com.sun.source.util" + }; + + private static final Set comSunSourceAcceptable; + + static { + javaxLangModelAcceptable = new HashSet<>(Arrays.asList( + "java.io.", + "java.lang.", + "java.net.", + "java.nio.", + "java.util.", + "javax.lang.model.", + "javax.annotation.processing.SupportedSourceVersion", + "jdk.Exported" + )); + Set javaxToolsProcessingAcceptableTemp = new HashSet<>(); + javaxToolsProcessingAcceptableTemp.addAll(javaxLangModelAcceptable); + javaxToolsProcessingAcceptableTemp.addAll(Arrays.asList( + "javax.annotation.processing.", + "javax.tools." + )); + javaxToolsProcessingAcceptable = javaxToolsProcessingAcceptableTemp; + Set comSunSourceAcceptableTemp = new HashSet<>(); + comSunSourceAcceptableTemp.addAll(javaxToolsProcessingAcceptable); + comSunSourceAcceptableTemp.addAll(Arrays.asList( + "com.sun.source.doctree.", + "com.sun.source.tree.", + "com.sun.source.util." + )); + comSunSourceAcceptable = comSunSourceAcceptableTemp; + } + + @Override + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + verifyPackage(javaxLangModelPackages, javaxLangModelAcceptable); + verifyPackage(javaxToolsProcessingPackages, javaxToolsProcessingAcceptable); + verifyPackage(comSunSourcePackages, comSunSourceAcceptable); + } + return true; + } + + private void verifyPackage(String[] packagesToTest, Set acceptable) { + for (String packageToTest : packagesToTest) { + PackageElement packageElement = processingEnv.getElementUtils() + .getPackageElement(packageToTest); + + verifyReferredTypesAcceptable(packageElement, acceptable); + } + } + + private void verifyReferredTypesAcceptable(Element rootElement, + final Set acceptable) { + new ElementScanner8() { + @Override public Void visitType(TypeElement e, Void p) { + verifyTypeAcceptable(e.getSuperclass(), acceptable); + verifyTypesAcceptable(e.getInterfaces(), acceptable); + scan(e.getTypeParameters(), p); + scan(e.getEnclosedElements(), p); + verifyAnnotations(e.getAnnotationMirrors(), acceptable); + return null; + } + @Override public Void visitTypeParameter(TypeParameterElement e, Void p) { + verifyTypesAcceptable(e.getBounds(), acceptable); + scan(e.getEnclosedElements(), p); + verifyAnnotations(e.getAnnotationMirrors(), acceptable); + return null; + } + @Override public Void visitPackage(PackageElement e, Void p) { + scan(e.getEnclosedElements(), p); + verifyAnnotations(e.getAnnotationMirrors(), acceptable); + return null; + } + @Override public Void visitVariable(VariableElement e, Void p) { + verifyTypeAcceptable(e.asType(), acceptable); + scan(e.getEnclosedElements(), p); + verifyAnnotations(e.getAnnotationMirrors(), acceptable); + return null; + } + @Override + public Void visitExecutable(ExecutableElement e, Void p) { + scan(e.getTypeParameters(), p); + verifyTypeAcceptable(e.getReturnType(), acceptable); + scan(e.getParameters(), p); + verifyTypesAcceptable(e.getThrownTypes(), acceptable); + scan(e.getEnclosedElements(), p); + verifyAnnotations(e.getAnnotationMirrors(), acceptable); + return null; + } + }.scan(rootElement, null); + } + + private void verifyAnnotations(Iterable annotations, + Set acceptable) { + for (AnnotationMirror mirror : annotations) { + Element annotationElement = mirror.getAnnotationType().asElement(); + + if (annotationElement.getAnnotation(Documented.class) == null) { + note("Ignoring undocumented annotation: " + mirror.getAnnotationType()); + } + + verifyTypeAcceptable(mirror.getAnnotationType(), acceptable); + + for (AnnotationValue value : mirror.getElementValues().values()) { + verifyAnnotationValue(value, acceptable); + } + } + } + + private void verifyAnnotationValue(AnnotationValue value, + final Set acceptable) { + value.accept(new SimpleAnnotationValueVisitor8() { + @Override public Void visitType(TypeMirror t, Void p) { + verifyTypeAcceptable(t, acceptable); + return null; + } + @Override + public Void visitEnumConstant(VariableElement c, Void p) { + verifyReferredTypesAcceptable(c, acceptable); + return null; + } + @Override public Void visitArray(List vals, + Void p) { + for (AnnotationValue val : vals) { + val.accept(this, p); + } + return null; + } + @Override protected Void defaultAction(Object o, Void p) { + error("Unexpected AnnotationValue: " + o.toString()); + return super.defaultAction(o, p); + } + }, null); + } + + private void verifyTypesAcceptable(Iterable types, + Set acceptable) { + if (types == null) return ; + + for (TypeMirror type : types) { + verifyTypeAcceptable(type, acceptable); + } + } + + private void verifyTypeAcceptable(TypeMirror type, Set acceptable) { + if (type == null) return ; + + verifyAnnotations(type.getAnnotationMirrors(), acceptable); + + switch (type.getKind()) { + case BOOLEAN: case BYTE: case CHAR: case DOUBLE: case FLOAT: + case INT: case LONG: case SHORT: case VOID: case NONE: case NULL: + return ; + case DECLARED: + DeclaredType dt = (DeclaredType) type; + TypeElement outermostTypeElement = outermostTypeElement(dt.asElement()); + String outermostType = outermostTypeElement.getQualifiedName().toString(); + boolean isAcceptable = false; + for (String acceptablePackage : acceptable) { + if (outermostType.startsWith(acceptablePackage)) { + isAcceptable = true; + break; + } + } + if (!isAcceptable) { + error("Type not acceptable for this API: " + dt.toString()); + } + + for (TypeMirror bound : dt.getTypeArguments()) { + verifyTypeAcceptable(bound, acceptable); + } + break; + case ARRAY: + verifyTypeAcceptable(((ArrayType) type).getComponentType(), acceptable); + break; + case INTERSECTION: + for (TypeMirror element : ((IntersectionType) type).getBounds()) { + verifyTypeAcceptable(element, acceptable); + } + break; + case TYPEVAR: + verifyTypeAcceptable(((TypeVariable) type).getLowerBound(), acceptable); + verifyTypeAcceptable(((TypeVariable) type).getUpperBound(), acceptable); + break; + case WILDCARD: + verifyTypeAcceptable(((WildcardType) type).getExtendsBound(), acceptable); + verifyTypeAcceptable(((WildcardType) type).getSuperBound(), acceptable); + break; + default: + error("Type not acceptable for this API: " + type.toString()); + break; + + } + } + + private TypeElement outermostTypeElement(Element el) { + while (el.getEnclosingElement().getKind() != ElementKind.PACKAGE) { + el = el.getEnclosingElement(); + } + + return (TypeElement) el; + } + + private void error(String text) { + processingEnv.getMessager().printMessage(Kind.ERROR, text); + } + + private void note(String text) { + processingEnv.getMessager().printMessage(Kind.NOTE, text); + } +} From 00478aa3b7f29a5a185bac12652eabfbec8e601c Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Tue, 15 Oct 2013 08:24:31 -0700 Subject: [PATCH 092/152] 7165611: implement Full Debug Symbols on MacOS X hotspot Add MacOS X FDS support to hotspot; add minimal MacOS X FDS import support to jdk; add MacOS X FDS support to install; add MacOS X FDS support to root. Reviewed-by: erikj, sla, dholmes, rdurbin, tbell, ihse --- common/autoconf/basics.m4 | 1 + common/autoconf/generated-configure.sh | 69 ++++++++++++++-- common/autoconf/hotspot-spec.gmk.in | 5 +- common/autoconf/jdk-options.m4 | 10 +-- common/autoconf/spec.gmk.in | 1 + common/makefiles/NativeCompilation.gmk | 108 ++++++++++++++----------- 6 files changed, 133 insertions(+), 61 deletions(-) diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index f3911ff9bd9..3788800362e 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -644,6 +644,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then fi if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then + BASIC_REQUIRE_PROG(DSYMUTIL, dsymutil) BASIC_REQUIRE_PROG(XATTR, xattr) AC_PATH_PROG(CODESIGN, codesign) if test "x$CODESIGN" != "x"; then diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index d09935154a7..2351570b4cb 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -824,6 +824,7 @@ OS_VERSION_MINOR OS_VERSION_MAJOR PKG_CONFIG CODESIGN +DSYMUTIL XATTR IS_GNU_TIME TIME @@ -10594,6 +10595,64 @@ $as_echo "no" >&6; } $as_echo "yes" >&6; } fi fi + + + for ac_prog in dsymutil +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DSYMUTIL in + [\\/]* | ?:[\\/]*) + ac_cv_path_DSYMUTIL="$DSYMUTIL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DSYMUTIL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +DSYMUTIL=$ac_cv_path_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DSYMUTIL" && break +done + + + if test "x$DSYMUTIL" = x; then + if test "xdsymutil" = x; then + PROG_NAME=dsymutil + else + PROG_NAME=dsymutil + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $PROG_NAME!" >&5 +$as_echo "$as_me: Could not find $PROG_NAME!" >&6;} + as_fn_error $? "Cannot continue" "$LINENO" 5 + fi fi @@ -29549,11 +29608,11 @@ if test "x$enable_debug_symbols" = "xyes"; then elif test "x$enable_debug_symbols" = "xno"; then ENABLE_DEBUG_SYMBOLS=false else - # default on macosx is false - if test "x$OPENJDK_TARGET_OS" = xmacosx; then - ENABLE_DEBUG_SYMBOLS=false - # Default is on if objcopy is found, otherwise off - elif test "x$OBJCOPY" != x || test "x$OPENJDK_TARGET_OS" = xwindows; then + # Default is on if objcopy is found + if test "x$OBJCOPY" != x; then + ENABLE_DEBUG_SYMBOLS=true + # MacOS X and Windows don't use objcopy but default is on for those OSes + elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then ENABLE_DEBUG_SYMBOLS=true else ENABLE_DEBUG_SYMBOLS=false diff --git a/common/autoconf/hotspot-spec.gmk.in b/common/autoconf/hotspot-spec.gmk.in index 17b404a5902..df9cde440f3 100644 --- a/common/autoconf/hotspot-spec.gmk.in +++ b/common/autoconf/hotspot-spec.gmk.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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 @@ -123,8 +123,7 @@ endif # Hotspot expects the variable ZIP_DEBUGINFO_FILES=1/0 and not true/false. ifeq ($(ZIP_DEBUGINFO_FILES)$(ENABLE_DEBUG_SYMBOLS), truetrue) ZIP_DEBUGINFO_FILES:=1 -endif -ifeq ($(ZIP_DEBUGINFO_FILES), false) +else ZIP_DEBUGINFO_FILES:=0 endif diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 188060740d7..c7b4dd46ea8 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -518,11 +518,11 @@ if test "x$enable_debug_symbols" = "xyes"; then elif test "x$enable_debug_symbols" = "xno"; then ENABLE_DEBUG_SYMBOLS=false else - # default on macosx is false - if test "x$OPENJDK_TARGET_OS" = xmacosx; then - ENABLE_DEBUG_SYMBOLS=false - # Default is on if objcopy is found, otherwise off - elif test "x$OBJCOPY" != x || test "x$OPENJDK_TARGET_OS" = xwindows; then + # Default is on if objcopy is found + if test "x$OBJCOPY" != x; then + ENABLE_DEBUG_SYMBOLS=true + # MacOS X and Windows don't use objcopy but default is on for those OSes + elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then ENABLE_DEBUG_SYMBOLS=true else ENABLE_DEBUG_SYMBOLS=false diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index 163fbc9a90d..a1474a3c626 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -485,6 +485,7 @@ CUT:=@CUT@ DATE:=@DATE@ DIFF:=@DIFF@ DIRNAME:=@DIRNAME@ +DSYMUTIL:=@DSYMUTIL@ FIND:=@FIND@ FIND_DELETE:=@FIND_DELETE@ ECHO:=@ECHO@ diff --git a/common/makefiles/NativeCompilation.gmk b/common/makefiles/NativeCompilation.gmk index 24448e86ebc..62143f8d1e3 100644 --- a/common/makefiles/NativeCompilation.gmk +++ b/common/makefiles/NativeCompilation.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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 @@ -435,31 +435,36 @@ define SetupNativeCompilation $(CP) $$< $$@ endif - ifeq ($(OPENJDK_TARGET_OS), solaris) - # gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. - # Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from - # empty section headers until a fixed $(OBJCOPY) is available. - # An empty section header has sh_addr == 0 and sh_size == 0. - # This problem has only been seen on Solaris X64, but we call this tool - # on all Solaris builds just in case. - # - # $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. - # Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. - $$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET) \ - $(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK) - $(RM) $$@ - $(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$< - $(OBJCOPY) --only-keep-debug $$< $$@ - $(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$< - else # not solaris - $$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET) - $(RM) $$@ - $(OBJCOPY) --only-keep-debug $$< $$@ - $(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$< - endif # Touch to not retrigger rule on rebuild + ifneq ($(OPENJDK_TARGET_OS), macosx) # OBJCOPY is not used on MacOS X + ifneq ($(OPENJDK_TARGET_OS), windows) # nor on Windows + ifeq ($(OPENJDK_TARGET_OS), solaris) + # gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. + # Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from + # empty section headers until a fixed $(OBJCOPY) is available. + # An empty section header has sh_addr == 0 and sh_size == 0. + # This problem has only been seen on Solaris X64, but we call this tool + # on all Solaris builds just in case. + # + # $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. + # Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. + $$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET) \ + $(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK) + $(RM) $$@ + $(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$< + $(OBJCOPY) --only-keep-debug $$< $$@ + $(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$< + else # not solaris + $$($1_OBJECT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo : $$($1_TARGET) + $(RM) $$@ + $(OBJCOPY) --only-keep-debug $$< $$@ + $(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$< + endif # Touch to not retrigger rule on rebuild $(TOUCH) $$@ + endif # !windows + endif # !macosx ifeq ($(ZIP_DEBUGINFO_FILES), true) + ifneq ($(OPENJDK_TARGET_OS), macosx) # no MacOS X support yet $1 += $$($1_OUTPUT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).diz ifeq ($(OPENJDK_TARGET_OS), windows) @@ -472,11 +477,12 @@ define SetupNativeCompilation $(CD) $$($1_OBJECT_DIR) \ && $(ZIP) -q $$@ $$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo endif + endif # no MacOS X support yet else ifeq ($(OPENJDK_TARGET_OS), windows) $1 += $$($1_OUTPUT_DIR)/$$($1_LIBRARY).map \ $$($1_OUTPUT_DIR)/$$($1_LIBRARY).pdb - else + else ifneq ($(OPENJDK_TARGET_OS), macosx) # MacOS X does not use .debuginfo files $1 += $$($1_OUTPUT_DIR)/$$(LIBRARY_PREFIX)$$($1_LIBRARY).debuginfo endif endif @@ -513,31 +519,36 @@ define SetupNativeCompilation $(CP) $$< $$@ endif - ifeq ($(OPENJDK_TARGET_OS), solaris) - # gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. - # Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from - # empty section headers until a fixed $(OBJCOPY) is available. - # An empty section header has sh_addr == 0 and sh_size == 0. - # This problem has only been seen on Solaris X64, but we call this tool - # on all Solaris builds just in case. - # - # $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. - # Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. - $$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET) \ - $(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK) - $(RM) $$@ - $(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$< - $(OBJCOPY) --only-keep-debug $$< $$@ - $(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$< - else # not solaris - $$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET) - $(RM) $$@ - $(OBJCOPY) --only-keep-debug $$< $$@ - $(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$< - endif - $(TOUCH) $$@ + ifneq ($(OPENJDK_TARGET_OS), macosx) # OBJCOPY is not used on MacOS X + ifneq ($(OPENJDK_TARGET_OS), windows) # nor on Windows + ifeq ($(OPENJDK_TARGET_OS), solaris) + # gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set. + # Use $(FIX_EMPTY_SEC_HDR_FLAGS) to clear the SHF_ALLOC flag (if set) from + # empty section headers until a fixed $(OBJCOPY) is available. + # An empty section header has sh_addr == 0 and sh_size == 0. + # This problem has only been seen on Solaris X64, but we call this tool + # on all Solaris builds just in case. + # + # $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections. + # Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available. + $$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET) \ + $(FIX_EMPTY_SEC_HDR_FLAGS) $(ADD_GNU_DEBUGLINK) + $(RM) $$@ + $(FIX_EMPTY_SEC_HDR_FLAGS) $(LOG_INFO) $$< + $(OBJCOPY) --only-keep-debug $$< $$@ + $(CD) $$(@D) && $(ADD_GNU_DEBUGLINK) $(LOG_INFO) $$(@F) $$< + else # not solaris + $$($1_OBJECT_DIR)/$$($1_PROGRAM).debuginfo : $$($1_TARGET) + $(RM) $$@ + $(OBJCOPY) --only-keep-debug $$< $$@ + $(CD) $$(@D) && $(OBJCOPY) --add-gnu-debuglink=$$(@F) $$< + endif + $(TOUCH) $$@ + endif # !windows + endif # !macosx ifeq ($(ZIP_DEBUGINFO_FILES), true) + ifneq ($(OPENJDK_TARGET_OS), macosx) # no MacOS X support yet $1 += $$($1_OUTPUT_DIR)/$$($1_PROGRAM).diz ifeq ($(OPENJDK_TARGET_OS), windows) @@ -550,11 +561,12 @@ define SetupNativeCompilation $(CD) $$($1_OBJECT_DIR) \ && $(ZIP) -q $$@ $$($1_PROGRAM).debuginfo endif + endif # no MacOS X support yet else ifeq ($(OPENJDK_TARGET_OS), windows) $1 += $$($1_OUTPUT_DIR)/$$($1_PROGRAM).map \ $$($1_OUTPUT_DIR)/$$($1_PROGRAM).pdb - else + else ifneq ($(OPENJDK_TARGET_OS), macosx) # MacOS X does not use .debuginfo files $1 += $$($1_OUTPUT_DIR)/$$($1_PROGRAM).debuginfo endif endif From 232c4efbdb04323d82e1a0085190284f92656b7d Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Tue, 15 Oct 2013 08:25:43 -0700 Subject: [PATCH 093/152] 7165611: implement Full Debug Symbols on MacOS X hotspot Add MacOS X FDS support to hotspot; add minimal MacOS X FDS import support to jdk; add MacOS X FDS support to install; add MacOS X FDS support to root. Reviewed-by: erikj, sla, dholmes, rdurbin, tbell, ihse --- hotspot/make/Makefile | 21 +++ hotspot/make/bsd/Makefile | 5 +- hotspot/make/bsd/makefiles/buildtree.make | 10 ++ hotspot/make/bsd/makefiles/defs.make | 203 +++++++++++++++++++++- hotspot/make/bsd/makefiles/dtrace.make | 128 +++++++++++++- hotspot/make/bsd/makefiles/gcc.make | 35 ++++ hotspot/make/bsd/makefiles/jsig.make | 45 ++++- hotspot/make/bsd/makefiles/product.make | 26 +-- hotspot/make/bsd/makefiles/saproc.make | 53 +++++- hotspot/make/bsd/makefiles/universal.gmk | 22 +-- hotspot/make/bsd/makefiles/vm.make | 60 ++++++- hotspot/make/defs.make | 10 ++ 12 files changed, 565 insertions(+), 53 deletions(-) diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile index 2975088cb49..581a5daae12 100644 --- a/hotspot/make/Makefile +++ b/hotspot/make/Makefile @@ -334,6 +334,11 @@ $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_BUILD_DIR)/%.diz $(install-file) $(EXPORT_SERVER_DIR)/64/%.diz: $(C2_BUILD_DIR)/%.diz $(install-file) +# MacOS X +$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: $(C2_BUILD_DIR)/%.dSYM + $(install-dir) +$(EXPORT_SERVER_DIR)/%.dSYM: $(C2_BUILD_DIR)/%.dSYM + $(install-dir) endif # Client (C1) @@ -379,6 +384,11 @@ $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_BUILD_DIR)/%.diz $(install-file) $(EXPORT_CLIENT_DIR)/64/%.diz: $(C1_BUILD_DIR)/%.diz $(install-file) +# MacOS X +$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: $(C1_BUILD_DIR)/%.dSYM + $(install-dir) +$(EXPORT_CLIENT_DIR)/%.dSYM: $(C1_BUILD_DIR)/%.dSYM + $(install-dir) endif # Minimal1 @@ -424,6 +434,7 @@ $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(MINIMAL1_BUILD_DIR)/%.diz $(install-file) $(EXPORT_MINIMAL_DIR)/64/%.diz: $(MINIMAL1_BUILD_DIR)/%.diz $(install-file) +# MacOS X does not support Minimal1 config endif # Zero @@ -446,6 +457,11 @@ $(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_BUILD_DIR)/%.debuginfo $(install-file) $(EXPORT_SERVER_DIR)/%.diz: $(ZERO_BUILD_DIR)/%.diz $(install-file) +# MacOS X +$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: $(ZERO_BUILD_DIR)/%.dSYM + $(install-dir) +$(EXPORT_SERVER_DIR)/%.dSYM: $(ZERO_BUILD_DIR)/%.dSYM + $(install-dir) endif # Shark @@ -468,6 +484,11 @@ $(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_BUILD_DIR)/%.debuginfo $(install-file) $(EXPORT_SERVER_DIR)/%.diz: $(SHARK_BUILD_DIR)/%.diz $(install-file) +# MacOS X +$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: $(SHARK_BUILD_DIR)/%.dSYM + $(install-dir) +$(EXPORT_SERVER_DIR)/%.dSYM: $(SHARK_BUILD_DIR)/%.dSYM + $(install-dir) endif $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/code/% diff --git a/hotspot/make/bsd/Makefile b/hotspot/make/bsd/Makefile index d9058c24e25..2bec290e306 100644 --- a/hotspot/make/bsd/Makefile +++ b/hotspot/make/bsd/Makefile @@ -204,6 +204,7 @@ TARGETS_MINIMAL1 = $(addsuffix minimal1,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) LIBRARY_SUFFIX=$(LIBRARY_SUFFIX) BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) +BUILDTREE_VARS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) OBJCOPY=$(OBJCOPY) STRIP_POLICY=$(STRIP_POLICY) ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) ZIPEXE=$(ZIPEXE) BUILDTREE = $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_VARS) @@ -337,9 +338,11 @@ treeminimal1: $(SUBDIRS_MINIMAL1) # Doc target. This is the same for all build options. # Hence create a docs directory beside ...$(ARCH)_[...] +# We specify 'BUILD_FLAVOR=product' so that the proper +# ENABLE_FULL_DEBUG_SYMBOLS value is used. docs: checks $(QUIETLY) mkdir -p $(SUBDIR_DOCS) - $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) jvmtidocs + $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) BUILD_FLAVOR=product jvmtidocs # Synonyms for win32-like targets. compiler2: debug product diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make index ca9d19e0d23..88b141e94c5 100644 --- a/hotspot/make/bsd/makefiles/buildtree.make +++ b/hotspot/make/bsd/makefiles/buildtree.make @@ -261,6 +261,16 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "$(call gamma-path,commonsrc,os/posix/vm)"; \ [ -n "$(CFLAGS_BROWSE)" ] && \ echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \ + [ -n "$(ENABLE_FULL_DEBUG_SYMBOLS)" ] && \ + echo && echo "ENABLE_FULL_DEBUG_SYMBOLS = $(ENABLE_FULL_DEBUG_SYMBOLS)"; \ + [ -n "$(OBJCOPY)" ] && \ + echo && echo "OBJCOPY = $(OBJCOPY)"; \ + [ -n "$(STRIP_POLICY)" ] && \ + echo && echo "STRIP_POLICY = $(STRIP_POLICY)"; \ + [ -n "$(ZIP_DEBUGINFO_FILES)" ] && \ + echo && echo "ZIP_DEBUGINFO_FILES = $(ZIP_DEBUGINFO_FILES)"; \ + [ -n "$(ZIPEXE)" ] && \ + echo && echo "ZIPEXE = $(ZIPEXE)"; \ [ -n "$(HOTSPOT_EXTRA_SYSDEFS)" ] && \ echo && \ echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \ diff --git a/hotspot/make/bsd/makefiles/defs.make b/hotspot/make/bsd/makefiles/defs.make index 14d3d4aa2ca..7cd21cc1753 100644 --- a/hotspot/make/bsd/makefiles/defs.make +++ b/hotspot/make/bsd/makefiles/defs.make @@ -136,10 +136,127 @@ ifeq ($(JVM_VARIANTS),) endif endif +OS_VENDOR:=$(shell uname -s) + +# determine if HotSpot is being built in JDK6 or earlier version +JDK6_OR_EARLIER=0 +ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1" + # if the longer variable names (newer build style) are set, then check those + ifeq "$(shell expr \( $(JDK_MAJOR_VERSION) = 1 \& $(JDK_MINOR_VERSION) \< 7 \))" "1" + JDK6_OR_EARLIER=1 + endif +else + # the longer variables aren't set so check the shorter variable names + ifeq "$(shell expr \( '$(JDK_MAJOR_VER)' = 1 \& '$(JDK_MINOR_VER)' \< 7 \))" "1" + JDK6_OR_EARLIER=1 + endif +endif + +ifeq ($(JDK6_OR_EARLIER),0) + # Full Debug Symbols is supported on JDK7 or newer. + # The Full Debug Symbols (FDS) default for BUILD_FLAVOR == product + # builds is enabled with debug info files ZIP'ed to save space. For + # BUILD_FLAVOR != product builds, FDS is always enabled, after all a + # debug build without debug info isn't very useful. + # The ZIP_DEBUGINFO_FILES option only has meaning when FDS is enabled. + # + # If you invoke a build with FULL_DEBUG_SYMBOLS=0, then FDS will be + # disabled for a BUILD_FLAVOR == product build. + # + # Note: Use of a different variable name for the FDS override option + # versus the FDS enabled check is intentional (FULL_DEBUG_SYMBOLS + # versus ENABLE_FULL_DEBUG_SYMBOLS). For auto build systems that pass + # in options via environment variables, use of distinct variables + # prevents strange behaviours. For example, in a BUILD_FLAVOR != + # product build, the FULL_DEBUG_SYMBOLS environment variable will be + # 0, but the ENABLE_FULL_DEBUG_SYMBOLS make variable will be 1. If + # the same variable name is used, then different values can be picked + # up by different parts of the build. Just to be clear, we only need + # two variable names because the incoming option value can be + # overridden in some situations, e.g., a BUILD_FLAVOR != product + # build. + + # Due to the multiple sub-make processes that occur this logic gets + # executed multiple times. We reduce the noise by at least checking that + # BUILD_FLAVOR has been set. + ifneq ($(BUILD_FLAVOR),) + ifeq ($(BUILD_FLAVOR), product) + FULL_DEBUG_SYMBOLS ?= 1 + ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) + else + # debug variants always get Full Debug Symbols (if available) + ENABLE_FULL_DEBUG_SYMBOLS = 1 + endif + _JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") + # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later + + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + # MacOS X doesn't use OBJCOPY or STRIP_POLICY + OBJCOPY= + STRIP_POLICY= + ZIP_DEBUGINFO_FILES ?= 1 + else + # Default OBJCOPY comes from GNU Binutils on BSD + ifeq ($(CROSS_COMPILE_ARCH),) + DEF_OBJCOPY=/usr/bin/objcopy + else + # Assume objcopy is part of the cross-compilation toolset + ifneq ($(ALT_COMPILER_PATH),) + DEF_OBJCOPY=$(ALT_COMPILER_PATH)/objcopy + endif + endif + OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) + ifneq ($(ALT_OBJCOPY),) + _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") + OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) + endif + + ifeq ($(OBJCOPY),) + _JUNK_ := $(shell \ + echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo" \ + "files. You may need to set ALT_OBJCOPY.") + ENABLE_FULL_DEBUG_SYMBOLS=0 + _JUNK_ := $(shell \ + echo >&2 "INFO:" \ + "ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") + else + _JUNK_ := $(shell \ + echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo" \ + "files.") + + # Library stripping policies for .debuginfo configs: + # all_strip - strips everything from the library + # min_strip - strips most stuff from the library; leaves + # minimum symbols + # no_strip - does not strip the library at all + # + # Oracle security policy requires "all_strip". A waiver was + # granted on 2011.09.01 that permits using "min_strip" in the + # Java JDK and Java JRE. + # + # Currently, STRIP_POLICY is only used when Full Debug Symbols + # is enabled. + # + STRIP_POLICY ?= min_strip + + _JUNK_ := $(shell \ + echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)") + + ZIP_DEBUGINFO_FILES ?= 1 + endif + + _JUNK_ := $(shell \ + echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)") + endif + endif # ENABLE_FULL_DEBUG_SYMBOLS=1 + endif # BUILD_FLAVOR +endif # JDK_6_OR_EARLIER + JDK_INCLUDE_SUBDIR=bsd # Library suffix -OS_VENDOR:=$(shell uname -s) ifeq ($(OS_VENDOR),Darwin) LIBRARY_SUFFIX=dylib else @@ -150,6 +267,19 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html # client and server subdirectories have symbolic links to ../libjsig.so EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX) + +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz + else + ifeq ($(OS_VENDOR), Darwin) + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX).dSYM + else + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo + endif + endif +endif + EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal @@ -157,34 +287,76 @@ EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true) EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX) + + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.diz + else + ifeq ($(OS_VENDOR), Darwin) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX).dSYM + else + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo + endif + endif + endif endif ifeq ($(JVM_VARIANT_CLIENT),true) EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX) + + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.diz + else + ifeq ($(OS_VENDOR), Darwin) + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX).dSYM + else + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo + endif + endif + endif endif ifeq ($(JVM_VARIANT_MINIMAL1),true) EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.$(LIBRARY_SUFFIX) - - ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) - ifeq ($(ZIP_DEBUGINFO_FILES),1) - EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.diz - else - EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.debuginfo - endif - endif endif # Serviceability Binaries # No SA Support for PPC, IA64, ARM or zero ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \ $(EXPORT_LIB_DIR)/sa-jdi.jar + +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + else + ifeq ($(OS_VENDOR), Darwin) + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM + else + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + endif + endif +endif + ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \ $(EXPORT_LIB_DIR)/sa-jdi.jar ADD_SA_BINARIES/universal = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \ $(EXPORT_LIB_DIR)/sa-jdi.jar + +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + ADD_SA_BINARIES/universal += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + else + ifeq ($(OS_VENDOR), Darwin) + ADD_SA_BINARIES/universal += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM + else + ADD_SA_BINARIES/universal += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + endif + endif +endif + ADD_SA_BINARIES/ppc = ADD_SA_BINARIES/ia64 = ADD_SA_BINARIES/arm = @@ -225,6 +397,19 @@ ifeq ($(OS_VENDOR), Darwin) # Files to simply copy in place UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/Xusage.txt UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/Xusage.txt + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.diz + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.diz + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.diz + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.diz + else + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX).dSYM + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX).dSYM + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX).dSYM + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM + endif + endif endif endif diff --git a/hotspot/make/bsd/makefiles/dtrace.make b/hotspot/make/bsd/makefiles/dtrace.make index 1c53841b56c..9374062d115 100644 --- a/hotspot/make/bsd/makefiles/dtrace.make +++ b/hotspot/make/bsd/makefiles/dtrace.make @@ -39,9 +39,15 @@ DtraceOutDir = $(GENERATED)/dtracefiles JVM_DB = libjvm_db LIBJVM_DB = libjvm_db.dylib +LIBJVM_DB_DEBUGINFO = libjvm_db.dylib.dSYM +LIBJVM_DB_DIZ = libjvm_db.diz + JVM_DTRACE = jvm_dtrace LIBJVM_DTRACE = libjvm_dtrace.dylib +LIBJVM_DTRACE_DEBUGINFO = libjvm_dtrace.dylib.dSYM +LIBJVM_DTRACE_DIZ = libjvm_dtrace.diz + JVMOFFS = JvmOffsets JVMOFFS.o = $(JVMOFFS).o GENOFFS = generate$(JVMOFFS) @@ -76,21 +82,87 @@ ISA = $(subst i386,i486,$(BUILDARCH)) # Making 64/libjvm_db.so: 64-bit version of libjvm_db.so which handles 32-bit libjvm.so ifneq ("${ISA}","${BUILDARCH}") -XLIBJVM_DB = 64/$(LIBJVM_DB) -XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE) +XLIBJVM_DIR = 64 +XLIBJVM_DB = $(XLIBJVM_DIR)/$(LIBJVM_DB) +XLIBJVM_DTRACE = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE) XARCH = $(subst sparcv9,v9,$(shell echo $(ISA))) +XLIBJVM_DB_DEBUGINFO = $(XLIBJVM_DIR)/$(LIBJVM_DB_DEBUGINFO) +XLIBJVM_DB_DIZ = $(XLIBJVM_DIR)/$(LIBJVM_DB_DIZ) +XLIBJVM_DTRACE_DEBUGINFO = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DEBUGINFO) +XLIBJVM_DTRACE_DIZ = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DIZ) + $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) @echo Making $@ - $(QUIETLY) mkdir -p 64/ ; \ + $(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \ $(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c #-lc +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) + # is not in the archived name: + ( cd $(XLIBJVM_DIR) && $(ZIPEXE) -q -r -y $(LIBJVM_DB_DIZ) $(LIBJVM_DB_DEBUGINFO) ) + $(RM) -r $(XLIBJVM_DB_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DB_DEBUGINFO) + # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) + # is not in the link name: + $(QUIETLY) ( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) ) + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -x $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) + # is not in the archived name: + ( cd $(XLIBJVM_DIR) && $(ZIPEXE) -q -y $(LIBJVM_DB_DIZ) $(LIBJVM_DB_DEBUGINFO) ) + $(RM) $(XLIBJVM_DB_DEBUGINFO) + endif + endif +endif $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo Making $@ - $(QUIETLY) mkdir -p 64/ ; \ + $(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \ $(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c #-lc -lthread -ldoor +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) + # is not in the archived name: + ( cd $(XLIBJVM_DIR) && $(ZIPEXE) -q -r -y $(LIBJVM_DTRACE_DIZ) $(LIBJVM_DTRACE_DEBUGINFO) ) + $(RM) -r $(XLIBJVM_DTRACE_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO) + # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) + # is not in the link name: + ( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) ) + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -x $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) + # is not in the archived name: + ( cd $(XLIBJVM_DIR) && $(ZIPEXE) -q -y $(LIBJVM_DTRACE_DIZ) $(LIBJVM_DTRACE_DEBUGINFO) ) + $(RM) $(XLIBJVM_DTRACE_DEBUGINFO) + endif + endif +endif endif # ifneq ("${ISA}","${BUILDARCH}") @@ -134,11 +206,59 @@ $(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_D @echo Making $@ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -Wall # -lc +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -r -y $(LIBJVM_DB_DIZ) $(LIBJVM_DB_DEBUGINFO) + $(RM) -r $(LIBJVM_DB_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DB_DEBUGINFO) + $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@ + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -x $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DB_DIZ) $(LIBJVM_DB_DEBUGINFO) + $(RM) $(LIBJVM_DB_DEBUGINFO) + endif + endif +endif $(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo Making $@ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c #-lc -lthread -ldoor +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -r -y $(LIBJVM_DTRACE_DIZ) $(LIBJVM_DTRACE_DEBUGINFO) + $(RM) -r $(LIBJVM_DTRACE_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO) + $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@ + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -x $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DTRACE_DIZ) $(LIBJVM_DTRACE_DEBUGINFO) + $(RM) $(LIBJVM_DTRACE_DEBUGINFO) + endif + endif +endif #$(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \ # $(DTRACE_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index 37c0268cdbe..840148e6321 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -83,6 +83,11 @@ ifeq ($(SPEC),) AS = $(CC) -c endif +ifeq ($(OS_VENDOR), Darwin) + ifeq ($(DSYMUTIL),) + DSYMUTIL=dsymutil + endif +endif ifeq ($(USE_CLANG), true) CC_VER_MAJOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f1) @@ -434,6 +439,36 @@ else ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) DEBUG_CFLAGS += -gstabs endif + + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + FASTDEBUG_CFLAGS/ia64 = -g + FASTDEBUG_CFLAGS/amd64 = -g + FASTDEBUG_CFLAGS/arm = -g + FASTDEBUG_CFLAGS/ppc = -g + FASTDEBUG_CFLAGS += $(FASTDEBUG_CFLAGS/$(BUILDARCH)) + ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),) + ifeq ($(USE_CLANG), true) + # Clang doesn't understand -gstabs + FASTDEBUG_CFLAGS += -g + else + FASTDEBUG_CFLAGS += -gstabs + endif + endif + + OPT_CFLAGS/ia64 = -g + OPT_CFLAGS/amd64 = -g + OPT_CFLAGS/arm = -g + OPT_CFLAGS/ppc = -g + OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH)) + ifeq ($(OPT_CFLAGS/$(BUILDARCH)),) + ifeq ($(USE_CLANG), true) + # Clang doesn't understand -gstabs + OPT_CFLAGS += -g + else + OPT_CFLAGS += -gstabs + endif + endif + endif endif # If we are building HEADLESS, pass on to VM diff --git a/hotspot/make/bsd/makefiles/jsig.make b/hotspot/make/bsd/makefiles/jsig.make index 481ff72f0b5..b4802fb5069 100644 --- a/hotspot/make/bsd/makefiles/jsig.make +++ b/hotspot/make/bsd/makefiles/jsig.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2013, Oracle and/or its affiliates. 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,13 +29,21 @@ JSIG = jsig ifeq ($(OS_VENDOR), Darwin) LIBJSIG = lib$(JSIG).dylib + + LIBJSIG_DEBUGINFO = lib$(JSIG).dylib.dSYM + LIBJSIG_DIZ = lib$(JSIG).diz else LIBJSIG = lib$(JSIG).so + + LIBJSIG_DEBUGINFO = lib$(JSIG).debuginfo + LIBJSIG_DIZ = lib$(JSIG).diz endif JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm -DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG) +DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG) +DEST_JSIG_DEBUGINFO = $(JDK_LIBDIR)/$(LIBJSIG_DEBUGINFO) +DEST_JSIG_DIZ = $(JDK_LIBDIR)/$(LIBJSIG_DIZ) LIBJSIG_MAPFILE = $(MAKEFILES_DIR)/mapfile-vers-jsig @@ -55,9 +63,42 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -r -y $(LIBJSIG_DIZ) $(LIBJSIG_DEBUGINFO) + $(RM) -r $(LIBJSIG_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) + $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -g $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJSIG_DIZ) $(LIBJSIG_DEBUGINFO) + $(RM) $(LIBJSIG_DEBUGINFO) + endif + endif +endif install_jsig: $(LIBJSIG) @echo "Copying $(LIBJSIG) to $(DEST_JSIG)" +ifeq ($(OS_VENDOR), Darwin) + $(QUIETLY) test -d $(LIBJSIG_DEBUGINFO) && \ + cp -f -r $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) +else + $(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ + cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) +endif + $(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done" .PHONY: install_jsig diff --git a/hotspot/make/bsd/makefiles/product.make b/hotspot/make/bsd/makefiles/product.make index 0d6fb0e86d0..55515469311 100644 --- a/hotspot/make/bsd/makefiles/product.make +++ b/hotspot/make/bsd/makefiles/product.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, Oracle and/or its affiliates. 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 @@ -43,15 +43,17 @@ MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-product SYSDEFS += -DPRODUCT VERSION = optimized -# use -g to strip library as -x will discard its symbol table; -x is fine for -# executables. -ifdef CROSS_COMPILE_ARCH - STRIP = $(ALT_COMPILER_PATH)/strip -else - STRIP = strip -endif -STRIP_LIBJVM = $(STRIP) -g $@ || exit 1; -STRIP_AOUT = $(STRIP) -x $@ || exit 1; +ifneq ($(OS_VENDOR), Darwin) + # use -g to strip library as -x will discard its symbol table; -x is fine for + # executables. + ifdef CROSS_COMPILE_ARCH + STRIP = $(ALT_COMPILER_PATH)/strip + else + STRIP = strip + endif + STRIP_LIBJVM = $(STRIP) -g $@ || exit 1; + STRIP_AOUT = $(STRIP) -x $@ || exit 1; -# Don't strip in VM build; JDK build will strip libraries later -# LINK_LIB.CXX/POST_HOOK += $(STRIP_$(LINK_INTO)) + # Don't strip in VM build; JDK build will strip libraries later + # LINK_LIB.CXX/POST_HOOK += $(STRIP_$(LINK_INTO)) +endif diff --git a/hotspot/make/bsd/makefiles/saproc.make b/hotspot/make/bsd/makefiles/saproc.make index 62e31a63dc0..8cb38dbca47 100644 --- a/hotspot/make/bsd/makefiles/saproc.make +++ b/hotspot/make/bsd/makefiles/saproc.make @@ -28,9 +28,15 @@ SAPROC = saproc ifeq ($(OS_VENDOR), Darwin) - LIBSAPROC = lib$(SAPROC).dylib + LIBSAPROC = lib$(SAPROC).dylib + + LIBSAPROC_DEBUGINFO = lib$(SAPROC).dylib.dSYM + LIBSAPROC_DIZ = lib$(SAPROC).diz else - LIBSAPROC = lib$(SAPROC).so + LIBSAPROC = lib$(SAPROC).so + + LIBSAPROC_DEBUGINFO = lib$(SAPROC).debuginfo + LIBSAPROC_DIZ = lib$(SAPROC).diz endif AGENT_DIR = $(GAMMADIR)/agent @@ -70,7 +76,9 @@ endif SAMAPFILE = $(SASRCDIR)/mapfile -DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC) +DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC) +DEST_SAPROC_DEBUGINFO = $(JDK_LIBDIR)/$(LIBSAPROC_DEBUGINFO) +DEST_SAPROC_DIZ = $(JDK_LIBDIR)/$(LIBSAPROC_DIZ) # DEBUG_BINARIES overrides everything, use full -g debug information ifeq ($(DEBUG_BINARIES), true) @@ -117,11 +125,42 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE) $(SA_DEBUG_CFLAGS) \ -o $@ \ $(SALIBS) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -r -y $(LIBSAPROC_DIZ) $(LIBSAPROC_DEBUGINFO) + $(RM) -r $(LIBSAPROC_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO) + $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@ + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -g $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBSAPROC_DIZ) $(LIBSAPROC_DEBUGINFO) + $(RM) $(LIBSAPROC_DEBUGINFO) + endif + endif +endif install_saproc: $(BUILDLIBSAPROC) - $(QUIETLY) if [ -e $(LIBSAPROC) ] ; then \ - echo "Copying $(LIBSAPROC) to $(DEST_SAPROC)"; \ - cp -f $(LIBSAPROC) $(DEST_SAPROC) && echo "Done"; \ - fi + @echo "Copying $(LIBSAPROC) to $(DEST_SAPROC)" +ifeq ($(OS_VENDOR), Darwin) + $(QUIETLY) test -d $(LIBSAPROC_DEBUGINFO) && \ + cp -f -r $(LIBSAPROC_DEBUGINFO) $(DEST_SAPROC_DEBUGINFO) +else + $(QUIETLY) test -f $(LIBSAPROC_DEBUGINFO) && \ + cp -f $(LIBSAPROC_DEBUGINFO) $(DEST_SAPROC_DEBUGINFO) +endif + $(QUIETLY) test -f $(LIBSAPROC_DIZ) && \ + cp -f $(LIBSAPROC_DIZ) $(DEST_SAPROC_DIZ) + $(QUIETLY) cp -f $(LIBSAPROC) $(DEST_SAPROC) && echo "Done" .PHONY: install_saproc diff --git a/hotspot/make/bsd/makefiles/universal.gmk b/hotspot/make/bsd/makefiles/universal.gmk index 0cc92758af9..d1136a86806 100644 --- a/hotspot/make/bsd/makefiles/universal.gmk +++ b/hotspot/make/bsd/makefiles/universal.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. 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 @@ -19,7 +19,7 @@ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. -# +# # # macosx universal builds @@ -35,15 +35,15 @@ universal_debug: all_product_universal: # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_PRODUCT_TARGETS) $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_PRODUCT_TARGETS) - $(QUIETLY) $(MAKE) EXPORT_SUBDIR= universalize + $(QUIETLY) $(MAKE) BUILD_FLAVOR=product EXPORT_SUBDIR= universalize all_fastdebug_universal: # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_FASTDEBUG_TARGETS) $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_FASTDEBUG_TARGETS) - $(QUIETLY) $(MAKE) EXPORT_SUBDIR=/fastdebug universalize + $(QUIETLY) $(MAKE) BUILD_FLAVOR=fastdebug EXPORT_SUBDIR=/fastdebug universalize all_debug_universal: # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_DEBUG_TARGETS) $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_DEBUG_TARGETS) - $(QUIETLY) $(MAKE) EXPORT_SUBDIR=/debug universalize + $(QUIETLY) $(MAKE) BUILD_FLAVOR=debug EXPORT_SUBDIR=/debug universalize # Consolidate architecture builds into a single Universal binary @@ -57,18 +57,18 @@ $(UNIVERSAL_LIPO_LIST): if [ -n "$${BUILT_LIPO_FILES}" ]; then \ $(MKDIR) -p $(shell dirname $@); \ lipo -create -output $@ $${BUILT_LIPO_FILES}; \ - fi + fi # Copy built non-universal binaries in place +# - copies directories; including empty dirs +# - copies files, symlinks, other non-directory files $(UNIVERSAL_COPY_LIST): - BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`"; \ + BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) -prune 2>/dev/null`"; \ if [ -n "$${BUILT_COPY_FILES}" ]; then \ for i in $${BUILT_COPY_FILES}; do \ - if [ -f $${i} ]; then \ - $(MKDIR) -p $(shell dirname $@); \ - $(CP) $${i} $@; \ - fi; \ + $(MKDIR) -p $(shell dirname $@); \ + $(CP) -R $${i} $@; \ done; \ fi diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make index ba2eb0756a3..3e8ea764066 100644 --- a/hotspot/make/bsd/makefiles/vm.make +++ b/hotspot/make/bsd/makefiles/vm.make @@ -60,10 +60,16 @@ Src_Dirs_I += $(GENERATED) # The order is important for the precompiled headers to work. INCLUDES += $(PRECOMPILED_HEADER_DIR:%=-I%) $(Src_Dirs_I:%=-I%) -ifeq (${VERSION}, debug) +# SYMFLAG is used by {jsig,saproc}.make +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + # always build with debug info when we can create .dSYM/.debuginfo files SYMFLAG = -g else - SYMFLAG = + ifeq (${VERSION}, debug) + SYMFLAG = -g + else + SYMFLAG = + endif endif # HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined @@ -147,8 +153,14 @@ ifeq ($(OS_VENDOR), Darwin) ifeq (${VERSION}, $(filter ${VERSION}, debug fastdebug)) CFLAGS += -DALLOW_OPERATOR_NEW_USAGE endif + + LIBJVM_DEBUGINFO = lib$(JVM).dylib.dSYM + LIBJVM_DIZ = lib$(JVM).diz else LIBJVM = lib$(JVM).so + + LIBJVM_DEBUGINFO = lib$(JVM).debuginfo + LIBJVM_DIZ = lib$(JVM).diz endif SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt @@ -322,10 +334,47 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT) rm -f $@.1; ln -s $@ $@.1; \ } -DEST_JVM = $(JDK_LIBDIR)/$(VM_SUBDIR)/$(LIBJVM) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_VENDOR), Darwin) + $(DSYMUTIL) $@ + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -r -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) + $(RM) -r $(LIBJVM_DEBUGINFO) + endif + else + $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO) + $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@ + ifeq ($(STRIP_POLICY),all_strip) + $(QUIETLY) $(STRIP) $@ + else + ifeq ($(STRIP_POLICY),min_strip) + $(QUIETLY) $(STRIP) -g $@ + # implied else here is no stripping at all + endif + endif + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) + $(RM) $(LIBJVM_DEBUGINFO) + endif + endif +endif + +DEST_SUBDIR = $(JDK_LIBDIR)/$(VM_SUBDIR) +DEST_JVM = $(DEST_SUBDIR)/$(LIBJVM) +DEST_JVM_DEBUGINFO = $(DEST_SUBDIR)/$(LIBJVM_DEBUGINFO) +DEST_JVM_DIZ = $(DEST_SUBDIR)/$(LIBJVM_DIZ) install_jvm: $(LIBJVM) @echo "Copying $(LIBJVM) to $(DEST_JVM)" +ifeq ($(OS_VENDOR), Darwin) + $(QUIETLY) test -d $(LIBJVM_DEBUGINFO) && \ + cp -f -r $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) +else + $(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ + cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) +endif + $(QUIETLY) test -f $(LIBJVM_DIZ) && \ + cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done" #---------------------------------------------------------------------- @@ -340,11 +389,8 @@ include $(MAKEFILES_DIR)/saproc.make #---------------------------------------------------------------------- ifeq ($(OS_VENDOR), Darwin) -$(LIBJVM).dSYM: $(LIBJVM) - dsymutil $(LIBJVM) - # no libjvm_db for macosx -build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM +build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck echo "Doing vm.make build:" else build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) diff --git a/hotspot/make/defs.make b/hotspot/make/defs.make index 5ebf167e290..ede0425bcb6 100644 --- a/hotspot/make/defs.make +++ b/hotspot/make/defs.make @@ -77,6 +77,16 @@ define install-file @$(RM) $@ $(CP) $< $@ endef + +# MacOS X strongly discourages 'cp -r' and provides 'cp -R' instead. +# May need to have a MacOS X specific definition of install-dir +# sometime in the future. +define install-dir +@$(MKDIR) -p $(@D) +@$(RM) -r $@ +$(CP) -r $< $@ +endef + define prep-target @$(MKDIR) -p $(@D) @$(RM) $@ From e54055bbb88b092c1ae8d8ec116fdad5169a7d42 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Tue, 15 Oct 2013 08:26:38 -0700 Subject: [PATCH 094/152] 7165611: implement Full Debug Symbols on MacOS X hotspot Add MacOS X FDS support to hotspot; add minimal MacOS X FDS import support to jdk; add MacOS X FDS support to install; add MacOS X FDS support to root. Reviewed-by: erikj, sla, dholmes, rdurbin, tbell, ihse --- jdk/make/common/Defs-macosx.gmk | 96 ++++++++++++++++++++++++++++++++- jdk/make/common/Defs.gmk | 30 ++++++++++- jdk/make/java/redist/Makefile | 49 ++++++++++------- jdk/makefiles/Import.gmk | 55 ++++++++++++++++--- jdk/makefiles/Tools.gmk | 2 + 5 files changed, 202 insertions(+), 30 deletions(-) diff --git a/jdk/make/common/Defs-macosx.gmk b/jdk/make/common/Defs-macosx.gmk index befd2cfed5b..83ccf604ac0 100644 --- a/jdk/make/common/Defs-macosx.gmk +++ b/jdk/make/common/Defs-macosx.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, Oracle and/or its affiliates. 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 @@ -85,6 +85,100 @@ SCRIPT_SUFFIX = CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required! CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required! +# The Full Debug Symbols (FDS) default for VARIANT == OPT builds is +# enabled with debug info files ZIP'ed to save space. For VARIANT != +# OPT builds, FDS is always enabled, after all a debug build without +# debug info isn't very useful. The ZIP_DEBUGINFO_FILES option only has +# meaning when FDS is enabled. +# +# If you invoke a build with FULL_DEBUG_SYMBOLS=0, then FDS will be +# disabled for a VARIANT == OPT build. +# +# Note: Use of a different variable name for the FDS override option +# versus the FDS enabled check is intentional (FULL_DEBUG_SYMBOLS +# versus ENABLE_FULL_DEBUG_SYMBOLS). For auto build systems that pass +# in options via environment variables, use of distinct variables +# prevents strange behaviours. For example, in a VARIANT != OPT build, +# the FULL_DEBUG_SYMBOLS environment variable will be 0, but the +# ENABLE_FULL_DEBUG_SYMBOLS make variable will be 1. If the same +# variable name is used, then different values can be picked up by +# different parts of the build. Just to be clear, we only need two +# variable names because the incoming option value can be overridden +# in some situations, e.g., a VARIANT != OPT build. + +ifeq ($(VARIANT), OPT) + FULL_DEBUG_SYMBOLS ?= 1 + ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) +else + # debug variants always get Full Debug Symbols (if available) + ENABLE_FULL_DEBUG_SYMBOLS = 1 +endif +_JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") +# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later + +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(OS_NAME),darwin) + # MacOS X doesn't use OBJCOPY or STRIP_POLICY + OBJCOPY= + STRIP_POLICY= + ZIP_DEBUGINFO_FILES ?= 1 + else + ifndef CROSS_COMPILE_ARCH + # Default OBJCOPY comes from GNU Binutils on Linux: + DEF_OBJCOPY=/usr/bin/objcopy + else + # Assume objcopy is part of the cross-compilation toolkit + DEF_OBJCOPY=$(COMPILER_PATH)/objcopy + endif + OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) + ifneq ($(ALT_OBJCOPY),) + _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") + # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path + OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) + endif + + # Setting ENABLE_FULL_DEBUG_SYMBOLS=1 (and OBJCOPY) above enables the + # JDK build to import .debuginfo or .diz files from the HotSpot build. + # However, adding FDS support to the JDK build will occur in phases + # so a different make variable (LIBRARY_SUPPORTS_FULL_DEBUG_SYMBOLS + # and PROGRAM_SUPPORTS_FULL_DEBUG_SYMBOLS) is used to indicate that a + # particular library or program supports FDS. + + ifeq ($(OBJCOPY),) + _JUNK_ := $(shell \ + echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo" \ + "files. You may need to set ALT_OBJCOPY.") + ENABLE_FULL_DEBUG_SYMBOLS=0 + else + _JUNK_ := $(shell \ + echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.") + + # Library stripping policies for .debuginfo configs: + # all_strip - strips everything from the library + # min_strip - strips most stuff from the library; leaves + # minimum symbols + # no_strip - does not strip the library at all + # + # Oracle security policy requires "all_strip". A waiver was granted + # on 2011.09.01 that permits using "min_strip" in the Java JDK and + # Java JRE. + # + # Currently, STRIP_POLICY is only used when Full Debug Symbols + # is enabled. + STRIP_POLICY ?= min_strip + + _JUNK_ := $(shell \ + echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)") + + ZIP_DEBUGINFO_FILES ?= 1 + endif + endif + + _JUNK_ := $(shell \ + echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)") +endif + # # Default optimization # diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index fe2bc94506f..5403664ff60 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1995, 2013, Oracle and/or its affiliates. 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 @@ -508,12 +508,18 @@ endef # Convenient macros # -# Prepare $@ target, remove old one and making sure directory exists +# Prepare $@ target, remove old one and making sure containing dir exists define prep-target $(MKDIR) -p $(@D) $(RM) $@ endef +# Prepare $@ target dir, remove old one and making sure containing dir exists +define prep-target-dir +$(MKDIR) -p $(@D) +$(RM) -r $@ +endef + # Simple install of $< file to $@ define install-file $(prep-target) @@ -616,6 +622,26 @@ $(CP) $< $@ fi endef +# MacOS X strongly discourages 'cp -r' and provides 'cp -R' instead. +# May need to have a MacOS X specific definition of install-import-dir +# sometime in the future. +define install-import-dir +@$(ECHO) "ASSEMBLY_IMPORT: $@" +$(prep-target-dir) +$(CP) -r $< $@ +endef + +ifeq ($(PLATFORM), macosx) +# On MacOS X, debug info is in .dSYM directories +define install-import-debuginfo +$(install-import-dir) +endef +else +define install-import-debuginfo +$(install-import-file) +endef +endif + define install-import-file $(install-importonly-file) endef diff --git a/jdk/make/java/redist/Makefile b/jdk/make/java/redist/Makefile index fb257f5c354..f06e5d1cedb 100644 --- a/jdk/make/java/redist/Makefile +++ b/jdk/make/java/redist/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,15 +60,24 @@ LIBJSIG_NAME = $(LIB_PREFIX)jsig.$(LIBRARY_SUFFIX) JVMDB_NAME = $(LIB_PREFIX)jvm$(DB_SUFFIX).$(LIBRARY_SUFFIX) JVMDTRACE_NAME = $(LIB_PREFIX)jvm$(DTRACE_SUFFIX).$(LIBRARY_SUFFIX) -JVM_DEBUGINFO_NAME = $(LIB_PREFIX)jvm.debuginfo JVM_DIZ_NAME = $(LIB_PREFIX)jvm.diz -LIBJSIG_DEBUGINFO_NAME = $(LIB_PREFIX)jsig.debuginfo LIBJSIG_DIZ_NAME = $(LIB_PREFIX)jsig.diz -JVMDB_DEBUGINFO_NAME = $(LIB_PREFIX)jvm$(DB_SUFFIX).debuginfo JVMDB_DIZ_NAME = $(LIB_PREFIX)jvm$(DB_SUFFIX).diz -JVMDTRACE_DEBUGINFO_NAME = $(LIB_PREFIX)jvm$(DTRACE_SUFFIX).debuginfo JVMDTRACE_DIZ_NAME = $(LIB_PREFIX)jvm$(DTRACE_SUFFIX).diz +ifeq ($(PLATFORM), macosx) + # Note: *.dSYM is a directory + JVM_DEBUGINFO_NAME = $(LIB_PREFIX)jvm.dSYM + LIBJSIG_DEBUGINFO_NAME = $(LIB_PREFIX)jsig.dSYM + JVMDB_DEBUGINFO_NAME = $(LIB_PREFIX)jvm$(DB_SUFFIX).dSYM + JVMDTRACE_DEBUGINFO_NAME = $(LIB_PREFIX)jvm$(DTRACE_SUFFIX).dSYM +else + JVM_DEBUGINFO_NAME = $(LIB_PREFIX)jvm.debuginfo + LIBJSIG_DEBUGINFO_NAME = $(LIB_PREFIX)jsig.debuginfo + JVMDB_DEBUGINFO_NAME = $(LIB_PREFIX)jvm$(DB_SUFFIX).debuginfo + JVMDTRACE_DEBUGINFO_NAME = $(LIB_PREFIX)jvm$(DTRACE_SUFFIX).debuginfo +endif + CLASSSHARINGDATA_DIR = $(BUILDDIR)/tools/sharing # Needed to do file copy @@ -441,7 +450,7 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_DIZ_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVM $(install-import-file) else $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_DEBUGINFO_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVM_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) endif endif @@ -459,7 +468,7 @@ $(LIB_LOCATION)/$(LIBJSIG_DIZ_NAME): $(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/$( $(install-import-file) else $(LIB_LOCATION)/$(LIBJSIG_DEBUGINFO_NAME): $(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/$(LIBJSIG_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) endif endif @@ -471,8 +480,8 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_NAME): ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) # We don't create a symlink to a libjsig.diz file, but we do put -# the libjsig.debuginfo symlink into a libjsig.diz file. The aurora -# system does not like dangling symlinks. +# the $(LIBJSIG_DEBUGINFO_NAME) symlink into a libjsig.diz file. +# The aurora system does not like dangling symlinks. ifeq ($(ZIP_DEBUGINFO_FILES),1) $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_DIZ_NAME) \ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_DIZ_NAME): @@ -496,8 +505,8 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME): ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) # We don't create a symlink to a libjsig.diz file, but we do put -# the libjsig.debuginfo symlink into a libjsig.diz file. The aurora -# system does not like dangling symlinks. +# the $(LIBJSIG_DEBUGINFO_NAME) symlink into a libjsig.diz file. +# The aurora system does not like dangling symlinks. ifeq ($(ZIP_DEBUGINFO_FILES),1) $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_DIZ_NAME): @$(prep-target) @@ -531,10 +540,10 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDB_DIZ_NAME): $(HOTSPOT_CLIENT_PATH)/ $(install-import-file) else $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDB_DEBUGINFO_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDB_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDB_DEBUGINFO_NAME): $(HOTSPOT_CLIENT_PATH)/64/$(JVMDB_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) endif endif @@ -556,10 +565,10 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_DIZ_NAME): $(HOTSPOT_SERVER_PATH)/ $(install-import-file) else $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_DEBUGINFO_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDB_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_DEBUGINFO_NAME): $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) endif endif endif @@ -581,10 +590,10 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDTRACE_DIZ_NAME): $(HOTSPOT_CLIENT_PA $(install-import-file) else $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDTRACE_DEBUGINFO_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDTRACE_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDTRACE_DEBUGINFO_NAME): $(HOTSPOT_CLIENT_PATH)/64/$(JVMDTRACE_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) endif endif @@ -613,13 +622,13 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVM_DIZ_NAME): $(HOTSPOT_SERVER_PATH)/$(JVM $(install-import-file) else $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDTRACE_DEBUGINFO_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDTRACE_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDTRACE_DEBUGINFO_NAME): $(HOTSPOT_SERVER_PATH)/64/$(JVMDTRACE_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVM_DEBUGINFO_NAME): $(HOTSPOT_SERVER_PATH)/$(JVM_DEBUGINFO_NAME) - $(install-import-file) + $(install-import-debuginfo) endif endif diff --git a/jdk/makefiles/Import.gmk b/jdk/makefiles/Import.gmk index d25a1829374..627f5e0b2d3 100644 --- a/jdk/makefiles/Import.gmk +++ b/jdk/makefiles/Import.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013, Oracle and/or its affiliates. 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 @@ -119,8 +119,13 @@ HOTSPOT_IMPORT_FILES:=$(addprefix $(LIBRARY_PREFIX), jvm.* saproc.* jsig.* sawin $(eval $(call CopyDir,HOTSPOT0, $(HOTSPOT_LIB_DIR), $(INSTALL_LIBRARIES_HERE), $(HOTSPOT_IMPORT_FILES))) $(eval $(call CopyDir,HOTSPOT1, $(HOTSPOT_DIST)/lib, $(JDK_OUTPUTDIR)/lib, $(HOTSPOT_IMPORT_FILES))) -JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \ - $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) +ifeq ($(OPENJDK_TARGET_OS), macosx) + JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.dSYM) \ + $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) +else + JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \ + $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) +endif ifneq ($(OPENJDK_TARGET_OS), windows) ifeq ($(JVM_VARIANT_SERVER), true) @@ -135,10 +140,12 @@ ifneq ($(OPENJDK_TARGET_OS), windows) IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I)) endif endif - ifeq ($(JVM_VARIANT_MINIMAL1), true) - IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) - ifneq (,$(JSIG_DEBUGINFO)) - IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I)) + ifneq ($(OPENJDK_TARGET_OS), macosx) + ifeq ($(JVM_VARIANT_MINIMAL1), true) + IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) + ifneq (,$(JSIG_DEBUGINFO)) + IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I)) + endif endif endif endif @@ -148,6 +155,21 @@ $(INSTALL_LIBRARIES_HERE)/server/%$(SHARED_LIBRARY_SUFFIX) : $(INSTALL_LIBRARIES $(RM) $@ $(LN) -s ../$(@F) $@ +ifeq ($(OPENJDK_TARGET_OS), macosx) +$(INSTALL_LIBRARIES_HERE)/server/%.dSYM : $(INSTALL_LIBRARIES_HERE)/%.dSYM + $(MKDIR) -p $(@D) + $(RM) $@ + $(LN) -s ../$(@F) $@ + +$(INSTALL_LIBRARIES_HERE)/server/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz + $(MKDIR) -p $(@D) + $(RM) $@ + $(RM) $@.tmp $(basename $@).dSYM + $(LN) -s ../$(basename $(@F)).dSYM $(basename $@).dSYM + $(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).dSYM + $(RM) $(basename $@).dSYM + $(MV) $@.tmp $@ +else $(INSTALL_LIBRARIES_HERE)/server/%.debuginfo : $(INSTALL_LIBRARIES_HERE)/%.debuginfo $(MKDIR) -p $(@D) $(RM) $@ @@ -161,12 +183,28 @@ $(INSTALL_LIBRARIES_HERE)/server/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz $(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo $(RM) $(basename $@).debuginfo $(MV) $@.tmp $@ +endif $(INSTALL_LIBRARIES_HERE)/client/%$(SHARED_LIBRARY_SUFFIX) : $(INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX) $(MKDIR) -p $(@D) $(RM) $@ $(LN) -s ../$(@F) $@ +ifeq ($(OPENJDK_TARGET_OS), macosx) +$(INSTALL_LIBRARIES_HERE)/client/%.dSYM : $(INSTALL_LIBRARIES_HERE)/%.dSYM + $(MKDIR) -p $(@D) + $(RM) $@ + $(LN) -s ../$(@F) $@ + +$(INSTALL_LIBRARIES_HERE)/client/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz + $(MKDIR) -p $(@D) + $(RM) $@ + $(RM) $@.tmp $(basename $@).dSYM + $(LN) -s ../$(basename $(@F)).dSYM $(basename $@).dSYM + $(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).dSYM + $(RM) $(basename $@).dSYM + $(MV) $@.tmp $@ +else $(INSTALL_LIBRARIES_HERE)/client/%.debuginfo : $(INSTALL_LIBRARIES_HERE)/%.debuginfo $(MKDIR) -p $(@D) $(RM) $@ @@ -180,12 +218,14 @@ $(INSTALL_LIBRARIES_HERE)/client/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz $(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo $(RM) $(basename $@).debuginfo $(MV) $@.tmp $@ +endif $(INSTALL_LIBRARIES_HERE)/minimal/%$(SHARED_LIBRARY_SUFFIX) : $(INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX) $(MKDIR) -p $(@D) $(RM) $@ $(LN) -s ../$(@F) $@ +ifneq ($(OPENJDK_TARGET_OS), macosx) $(INSTALL_LIBRARIES_HERE)/minimal/%.debuginfo : $(INSTALL_LIBRARIES_HERE)/%.debuginfo $(MKDIR) -p $(@D) $(RM) $@ @@ -199,6 +239,7 @@ $(INSTALL_LIBRARIES_HERE)/minimal/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz $(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo $(RM) $(basename $@).debuginfo $(MV) $@.tmp $@ +endif ########################################################################################## # Unpack the binary distributions of the crypto classes if they exist. diff --git a/jdk/makefiles/Tools.gmk b/jdk/makefiles/Tools.gmk index 9a7b2997b86..44cb360f634 100644 --- a/jdk/makefiles/Tools.gmk +++ b/jdk/makefiles/Tools.gmk @@ -154,6 +154,7 @@ TOOL_CHECKDEPS=$(JAVA) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/l # Tools needed on solaris because OBJCOPY is broken. +ifeq ($(OPENJDK_TARGET_OS), solaris) $(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK,\ SRC:=$(JDK_TOPDIR)/make/tools/add_gnu_debuglink,\ LANG:=C,\ @@ -173,3 +174,4 @@ $(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS,\ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags,\ OUTPUT_DIR:=$(JDK_OUTPUTDIR)/btbin,\ PROGRAM:=fix_empty_sec_hdr_flags)) +endif From fd29d64bfdfe9c111b8694d0caa041f2a71f2c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Tue, 15 Oct 2013 17:37:47 +0200 Subject: [PATCH 095/152] 8026367: Add a sync keyword to mozilla_compat Reviewed-by: sundar, attila, lagergren --- .../nashorn/api/scripting/ScriptUtils.java | 14 +++++ .../internal/objects/ScriptFunctionImpl.java | 7 +++ .../RecompilableScriptFunctionData.java | 8 +-- .../internal/runtime/ScriptFunction.java | 20 ++++++ .../internal/runtime/ScriptFunctionData.java | 8 +-- .../runtime/resources/mozilla_compat.js | 11 ++++ nashorn/test/script/basic/JDK-8026367.js | 61 +++++++++++++++++++ nashorn/test/script/sandbox/loadcompat.js | 4 ++ 8 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026367.js diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java index ccd5879b3f9..48045e1f336 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java @@ -25,6 +25,7 @@ package jdk.nashorn.api.scripting; +import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptRuntime; /** @@ -57,4 +58,17 @@ public final class ScriptUtils { public static String format(final String format, final Object[] args) { return Formatter.format(format, args); } + + /** + * Create a wrapper function that calls {@code func} synchronized on {@code sync} or, if that is undefined, + * {@code self}. Used to implement "sync" function in resources/mozilla_compat.js. + * + * @param func the function to invoke + * @param sync the object to synchronize on + * @return a synchronizing wrapper function + */ + public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) { + return func.makeSynchronizedFunction(sync); + } + } diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java index 88421a70bd1..638d18a2087 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java @@ -25,6 +25,7 @@ package jdk.nashorn.internal.objects; +import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.lang.invoke.MethodHandle; @@ -255,6 +256,12 @@ public class ScriptFunctionImpl extends ScriptFunction { return makeFunction(name, methodHandle, null); } + @Override + public ScriptFunction makeSynchronizedFunction(final Object sync) { + final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync); + return makeFunction(getName(), mh); + } + /** * Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we * can expose it to methods in this package. diff --git a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java index ef9324d9d6e..e5ca3c9a603 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java @@ -53,7 +53,7 @@ import jdk.nashorn.internal.parser.TokenType; public final class RecompilableScriptFunctionData extends ScriptFunctionData { /** FunctionNode with the code for this ScriptFunction */ - private volatile FunctionNode functionNode; + private FunctionNode functionNode; /** Source from which FunctionNode was parsed. */ private final Source source; @@ -65,7 +65,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData { private final PropertyMap allocatorMap; /** Code installer used for all further recompilation/specialization of this ScriptFunction */ - private volatile CodeInstaller installer; + private CodeInstaller installer; /** Name of class where allocator function resides */ private final String allocatorClassName; @@ -178,7 +178,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData { } @Override - protected void ensureCodeGenerated() { + protected synchronized void ensureCodeGenerated() { if (!code.isEmpty()) { return; // nothing to do, we have code, at least some. } @@ -336,7 +336,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData { } @Override - MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) { + synchronized MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) { final MethodType runtimeType = runtimeType(callSiteType, args); assert runtimeType.parameterCount() == callSiteType.parameterCount(); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java index 72658df07b8..ae59855cb4b 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java @@ -59,6 +59,9 @@ public abstract class ScriptFunction extends ScriptObject { /** Method handle for name getter for this ScriptFunction */ public static final MethodHandle G$NAME = findOwnMH("G$name", Object.class, Object.class); + /** Method handle used for implementing sync() in mozilla_compat */ + public static final MethodHandle INVOKE_SYNC = findOwnMH("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class); + /** Method handle for allocate function for this ScriptFunction */ static final MethodHandle ALLOCATE = findOwnMH("allocate", Object.class); @@ -300,6 +303,14 @@ public abstract class ScriptFunction extends ScriptObject { */ public abstract void setPrototype(Object prototype); + /** + * Create a function that invokes this function synchronized on {@code sync} or the self object + * of the invocation. + * @param sync the Object to synchronize on, or undefined + * @return synchronized function + */ + public abstract ScriptFunction makeSynchronizedFunction(Object sync); + /** * Return the most appropriate invoke handle if there are specializations * @param type most specific method type to look for invocation with @@ -614,6 +625,15 @@ public abstract class ScriptFunction extends ScriptObject { return result; } + @SuppressWarnings("unused") + private static Object invokeSync(final ScriptFunction func, final Object sync, final Object self, final Object... args) + throws Throwable { + final Object syncObj = sync == UNDEFINED ? self : sync; + synchronized (syncObj) { + return func.invoke(self, args); + } + } + private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { final Class own = ScriptFunction.class; final MethodType mt = MH.type(rtype, types); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java index 06a12c0096b..04c3ae8d258 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java @@ -675,7 +675,7 @@ public abstract class ScriptFunctionData { /** * Heuristic to figure out if the method handle has a callee argument. If it's type is either - * {@code (boolean, Object, ScriptFunction, ...)} or {@code (Object, ScriptFunction, ...)}, then we'll assume it has + * {@code (boolean, ScriptFunction, ...)} or {@code (ScriptFunction, ...)}, then we'll assume it has * a callee argument. We need this as the constructor above is not passed this information, and can't just blindly * assume it's false (notably, it's being invoked for creation of new scripts, and scripts have scopes, therefore * they also always receive a callee). @@ -692,11 +692,11 @@ public abstract class ScriptFunctionData { return false; } - if (type.parameterType(0) == boolean.class) { - return length > 1 && type.parameterType(1) == ScriptFunction.class; + if (type.parameterType(0) == ScriptFunction.class) { + return true; } - return type.parameterType(0) == ScriptFunction.class; + return length > 1 && type.parameterType(0) == boolean.class && type.parameterType(1) == ScriptFunction.class; } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js index f54dcfb8bf0..85e2161c004 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -98,6 +98,17 @@ Object.defineProperty(this, "importPackage", { } +// sync +Object.defineProperty(this, "sync", { + configurable: true, enumerable: false, writable: true, + value: function(func, syncobj) { + if (arguments.length < 1 || arguments.length > 2 ) { + throw "sync(function [,object]) parameter count mismatch"; + } + return Packages.jdk.nashorn.api.scripting.ScriptUtils.makeSynchronizedFunction(func, syncobj); + } +}); + // Object.prototype.__defineGetter__ Object.defineProperty(Object.prototype, "__defineGetter__", { configurable: true, enumerable: false, writable: true, diff --git a/nashorn/test/script/basic/JDK-8026367.js b/nashorn/test/script/basic/JDK-8026367.js new file mode 100644 index 00000000000..c5e12358381 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026367.js @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026367: Add a sync keyword to mozilla_compat + * + * @test + * @run + */ + +if (typeof sync === "undefined") { + load("nashorn:mozilla_compat.js"); +} + +var obj = { + count: 0, + // Sync called with one argument will synchronize on this-object of invocation + inc: sync(function(d) { + this.count += d; + }), + // Pass explicit object to synchronize on as second argument + dec: sync(function(d) { + this.count -= d; + }, obj) +}; + +var t1 = new java.lang.Thread(function() { + for (var i = 0; i < 100000; i++) obj.inc(1); +}); +var t2 = new java.lang.Thread(function() { + for (var i = 0; i < 100000; i++) obj.dec(1); +}); + +t1.start(); +t2.start(); +t1.join(); +t2.join(); + +if (obj.count !== 0) { + throw new Error("Expected count == 0, got " + obj.count); +} diff --git a/nashorn/test/script/sandbox/loadcompat.js b/nashorn/test/script/sandbox/loadcompat.js index e99f67f2116..f0338df7121 100644 --- a/nashorn/test/script/sandbox/loadcompat.js +++ b/nashorn/test/script/sandbox/loadcompat.js @@ -48,3 +48,7 @@ if (typeof JavaAdapter != 'function') { if (typeof importPackage != 'function') { fail("importPackage function is missing in compatibility script"); } + +if (typeof sync != 'function') { + fail("sync function is missing in compatibility script"); +} From 4ea77e09790d8f959fb54681e133569f052171d1 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Tue, 15 Oct 2013 13:14:04 -0300 Subject: [PATCH 096/152] 8026498: Revert: latest runsunspider.js tests contains several bugs Reviewed-by: sundar, hannesw --- nashorn/test/script/basic/runsunspider.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nashorn/test/script/basic/runsunspider.js b/nashorn/test/script/basic/runsunspider.js index 07d28b76c4b..84ce915c04f 100644 --- a/nashorn/test/script/basic/runsunspider.js +++ b/nashorn/test/script/basic/runsunspider.js @@ -205,7 +205,7 @@ var tests = [ return ret; }, expected: function() { - return -0.16906933525822856; + return -1.3524862408537381; } }, { name: 'access-binary-trees.js', @@ -213,7 +213,7 @@ var tests = [ return ret; }, expected: function() { - return -1; + return -4; } }, { name: 'access-fannkuch.js', @@ -244,7 +244,6 @@ var tests = [ return 230692593; } }, - /* Test is broken (not initializing dnaOutputString to "") { name: 'regexp-dna.js', actual: function() { return dnaOutputString; @@ -253,7 +252,6 @@ var tests = [ return "agggtaaa|tttaccct 0\n[cgt]gggtaaa|tttaccc[acg] 9\na[act]ggtaaa|tttacc[agt]t 27\nag[act]gtaaa|tttac[agt]ct 24\nagg[act]taaa|ttta[agt]cct 30\naggg[acg]aaa|ttt[cgt]ccct 9\nagggt[cgt]aa|tt[acg]accct 12\nagggta[cgt]a|t[acg]taccct 9\nagggtaa[cgt]|[acg]ttaccct 15\n"; } }, - */ { name: 'math-cordic.js', actual: function() { return total; From 99e02c21cdb25bd113dd751f63f0c1fd27f07b57 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Tue, 15 Oct 2013 11:20:27 -0700 Subject: [PATCH 097/152] 8026370: javadoc creates empty Reviewed-by: jjg --- .../formats/html/TagletWriterImpl.java | 3 +- .../formats/html/markup/ContentBuilder.java | 2 - .../doclets/formats/html/markup/HtmlTree.java | 7 +- .../javadoc/testTagOutput/TestTagOutput.java | 78 +++++++++++++++++++ .../testTagOutput/pkg1/DeprecatedTag.java | 44 +++++++++++ 5 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 langtools/test/com/sun/javadoc/testTagOutput/TestTagOutput.java create mode 100644 langtools/test/com/sun/javadoc/testTagOutput/pkg1/DeprecatedTag.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java index 95e9a74ed78..7ff2e2efc45 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java @@ -118,7 +118,8 @@ public class TagletWriterImpl extends TagletWriter { if (deprs.length > 0) { Content body = commentTagsToOutput(null, doc, deprs[0].inlineTags(), false); - result.addContent(HtmlTree.SPAN(HtmlStyle.italic, body)); + if (!body.isEmpty()) + result.addContent(HtmlTree.SPAN(HtmlStyle.italic, body)); } } else { if (Util.isDeprecated(member.containingClass())) { diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java index a58662763ba..58eb68c2443 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java @@ -41,8 +41,6 @@ public class ContentBuilder extends Content { @Override public void addContent(Content content) { nullCheck(content); - if ((content instanceof ContentBuilder) && content.isEmpty()) - return; ensureMutableContents(); if (content instanceof ContentBuilder) { contents.addAll(((ContentBuilder) content).contents); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java index e0badbe9ff6..8ad5fa2df83 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java @@ -102,7 +102,12 @@ public class HtmlTree extends Content { * @param tagContent tag content to be added */ public void addContent(Content tagContent) { - if (tagContent == HtmlTree.EMPTY || tagContent.isValid()) { + if (tagContent instanceof ContentBuilder) { + for (Content content: ((ContentBuilder)tagContent).contents) { + addContent(content); + } + } + else if (tagContent == HtmlTree.EMPTY || tagContent.isValid()) { if (content.isEmpty()) content = new ArrayList(); content.add(tagContent); diff --git a/langtools/test/com/sun/javadoc/testTagOutput/TestTagOutput.java b/langtools/test/com/sun/javadoc/testTagOutput/TestTagOutput.java new file mode 100644 index 00000000000..c7d5f7a186e --- /dev/null +++ b/langtools/test/com/sun/javadoc/testTagOutput/TestTagOutput.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8026370 + * @summary This test checks the generated tag output. + * @author Bhavesh Patel + * @library ../lib/ + * @build JavadocTester TestTagOutput + * @run main TestTagOutput + */ + +public class TestTagOutput extends JavadocTester { + + private static final String BUG_ID = "8026370"; + private static final String[][] TEST = { + {BUG_ID + FS + "pkg1" + FS + "DeprecatedTag.html", + "
          Deprecated. 
          "}, + {BUG_ID + FS + "pkg1" + FS + "DeprecatedTag.html", + "
          Deprecated. " + + "Do not use this.
          "}}; + + private static final String[][] NEGATED_TEST = { + {BUG_ID + FS + "pkg1" + FS + "DeprecatedTag.html", + "
          Deprecated." + + " 
          "}}; + + private static final String[] ARGS = + new String[] { + "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestTagOutput tester = new TestTagOutput(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/testTagOutput/pkg1/DeprecatedTag.java b/langtools/test/com/sun/javadoc/testTagOutput/pkg1/DeprecatedTag.java new file mode 100644 index 00000000000..cfb6d2348d7 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testTagOutput/pkg1/DeprecatedTag.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +public class DeprecatedTag { + + /** + * This method is deprecated. + * + * @deprecated + */ + public void deprecatedMethod() { + } + + /** + * This method is also deprecated. + * + * @deprecated Do not use this. + */ + public void deprecatedMethodWithDesc() { + } +} + From 53cc43916a767e899e49495729a474e6dbb52aa1 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 15 Oct 2013 19:36:45 +0100 Subject: [PATCH 098/152] 8025816: javac crash with method reference with a type variable as the site Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Resolve.java | 8 +--- ...ashMethodReferenceWithSiteTypeVarTest.java | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/T8025816/CrashMethodReferenceWithSiteTypeVarTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 87eb36668f4..b5c0cfe6b4e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -424,13 +424,14 @@ public class Resolve { */ private boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { + Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site; while (c != null && !(c.isSubClass(sym.owner, types) && (c.flags() & INTERFACE) == 0 && // In JLS 2e 6.6.2.1, the subclass restriction applies // only to instance fields and methods -- types are excluded // regardless of whether they are declared 'static' or not. - ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) + ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types)))) c = c.owner.enclClass(); return c != null; } @@ -2710,11 +2711,6 @@ public class Resolve { InferenceContext inferenceContext) { MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; - if (site.hasTag(TYPEVAR)) { - return resolveMemberReference(pos, env, referenceTree, site.getUpperBound(), - name, argtypes, typeargtypes, boxingAllowed, methodCheck, inferenceContext); - } - site = types.capture(site); ReferenceLookupHelper boundLookupHelper; diff --git a/langtools/test/tools/javac/lambda/T8025816/CrashMethodReferenceWithSiteTypeVarTest.java b/langtools/test/tools/javac/lambda/T8025816/CrashMethodReferenceWithSiteTypeVarTest.java new file mode 100644 index 00000000000..ba43479521e --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8025816/CrashMethodReferenceWithSiteTypeVarTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025816 + * @summary Compiler crash when default method call with method reference + * @compile CrashMethodReferenceWithSiteTypeVarTest.java + */ + +import java.util.Collection; +import java.util.Comparator; + +public class CrashMethodReferenceWithSiteTypeVarTest { + public void m1(Collection c, Comparator comp) {} + + public void m2(Collection c) { + m1(c, T::compareTo); + } +} From 1868655b894d18a74dfb99f0b694bda18ea66e58 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 15 Oct 2013 21:02:21 +0100 Subject: [PATCH 099/152] 8024947: javac should issue the potentially ambiguous overload warning only where the problem appears Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Check.java | 35 +++++-- .../PotentiallyAmbiguousWarningTest.java | 97 +++++++++++++++++++ .../PotentiallyAmbiguousWarningTest.out | 9 ++ 3 files changed, 133 insertions(+), 8 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.java create mode 100644 langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index d7290748eac..c19cdb9ced3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -2399,13 +2399,28 @@ public class Check { ClashFilter cf = new ClashFilter(site); //for each method m1 that is overridden (directly or indirectly) //by method 'sym' in 'site'... + + List potentiallyAmbiguousList = List.nil(); + boolean overridesAny = false; for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { - if (!sym.overrides(m1, site.tsym, types, false)) { - checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1); - continue; - } - //...check each method m2 that is a member of 'site' - for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { + if (!sym.overrides(m1, site.tsym, types, false)) { + if (m1 == sym) { + continue; + } + + if (!overridesAny) { + potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1); + } + continue; + } + + if (m1 != sym) { + overridesAny = true; + potentiallyAmbiguousList = List.nil(); + } + + //...check each method m2 that is a member of 'site' + for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { if (m2 == m1) continue; //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error @@ -2424,10 +2439,14 @@ public class Check { } } } + + if (!overridesAny) { + for (MethodSymbol m: potentiallyAmbiguousList) { + checkPotentiallyAmbiguousOverloads(pos, site, sym, m); + } + } } - - /** Check that all static methods accessible from 'site' are * mutually compatible (JLS 8.4.8). * diff --git a/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.java b/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.java new file mode 100644 index 00000000000..9c878b822de --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024947 + * @summary javac should issue the potentially ambiguous overload warning only + * where the problem appears + * @compile/fail/ref=PotentiallyAmbiguousWarningTest.out -XDrawDiagnostics -Werror -Xlint:overloads PotentiallyAmbiguousWarningTest.java + * @compile PotentiallyAmbiguousWarningTest.java + */ + +import java.util.function.*; + +public interface PotentiallyAmbiguousWarningTest { + + //a warning should be fired + interface I1 { + void foo(Consumer c); + void foo(IntConsumer c); + } + + //a warning should be fired + class C1 { + void foo(Consumer c) { } + void foo(IntConsumer c) { } + } + + interface I2 { + void foo(Consumer c); + } + + //a warning should be fired, J1 is provoking the issue + interface J1 extends I2 { + void foo(IntConsumer c); + } + + //no warning here, the issue is introduced in I1 + interface I3 extends I1 {} + + //no warning here, the issue is introduced in I1. I4 is just overriding an existing method + interface I4 extends I1 { + void foo(IntConsumer c); + } + + class C2 { + void foo(Consumer c) { } + } + + //a warning should be fired, D1 is provoking the issue + class D1 extends C2 { + void foo(IntConsumer c) { } + } + + //a warning should be fired, C3 is provoking the issue + class C3 implements I2 { + public void foo(Consumer c) { } + public void foo(IntConsumer c) { } + } + + //no warning here, the issue is introduced in C1 + class C4 extends C1 {} + + //no warning here, the issue is introduced in C1. C5 is just overriding an existing method + class C5 extends C1 { + void foo(IntConsumer c) {} + } + + interface I5 { + void foo(T c); + } + + //a warning should be fired, J2 is provoking the issue + interface J2 extends I5 { + void foo(Consumer c); + } +} diff --git a/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.out b/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.out new file mode 100644 index 00000000000..6011a886e3d --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.out @@ -0,0 +1,9 @@ +PotentiallyAmbiguousWarningTest.java:39:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.I1, foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.I1 +PotentiallyAmbiguousWarningTest.java:45:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.C1, foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.C1 +PotentiallyAmbiguousWarningTest.java:55:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.J1, foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.I2 +PotentiallyAmbiguousWarningTest.java:72:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.D1, foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.C2 +PotentiallyAmbiguousWarningTest.java:78:21: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.C3, foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.C3 +PotentiallyAmbiguousWarningTest.java:95:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.J2, foo(T), PotentiallyAmbiguousWarningTest.I5 +- compiler.err.warnings.and.werror +1 error +6 warnings From 912fc38c650b358028adbd595ca38f757ed8348f Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Tue, 15 Oct 2013 22:15:35 +0200 Subject: [PATCH 100/152] 8026510: The name of com.sun.tools.javac.comp.Annotate.Annotator is confusing A mostly automated rename Annotate.Annotator->Annotate.Worker and enterAnnotation->run. Reviewed-by: emc, jjg --- .../sun/tools/javac/code/SymbolMetadata.java | 4 +- .../sun/tools/javac/code/TypeAnnotations.java | 12 ++--- .../com/sun/tools/javac/comp/Annotate.java | 52 ++++++++++--------- .../com/sun/tools/javac/comp/Attr.java | 4 +- .../com/sun/tools/javac/comp/MemberEnter.java | 28 +++++----- .../com/sun/tools/javac/jvm/ClassReader.java | 14 ++--- 6 files changed, 58 insertions(+), 56 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java index 42564f67ed3..46d162b71fa 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java @@ -205,14 +205,14 @@ public class SymbolMetadata { // Queue a pass that will replace Attribute.Placeholders // with Attribute.Compound (made from synthesized containers). - ctx.annotateRepeated(new Annotate.Annotator() { + ctx.annotateRepeated(new Annotate.Worker() { @Override public String toString() { return "repeated annotation pass of: " + sym + " in: " + sym.owner; } @Override - public void enterAnnotation() { + public void run() { complete(ctx); } }); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 5d5b74d6993..cda3c0fa444 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -49,7 +49,7 @@ import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.comp.Annotate; -import com.sun.tools.javac.comp.Annotate.Annotator; +import com.sun.tools.javac.comp.Annotate.Worker; import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; @@ -116,13 +116,13 @@ public class TypeAnnotations { * This version only visits types in signatures and should be * called from MemberEnter. * The method takes the Annotate object as parameter and - * adds an Annotator to the correct Annotate queue for + * adds an Annotate.Worker to the correct Annotate queue for * later processing. */ public void organizeTypeAnnotationsSignatures(final Env env, final JCClassDecl tree) { - annotate.afterRepeated( new Annotator() { + annotate.afterRepeated( new Worker() { @Override - public void enterAnnotation() { + public void run() { JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); try { @@ -135,9 +135,9 @@ public class TypeAnnotations { } public void validateTypeAnnotationsSignatures(final Env env, final JCClassDecl tree) { - annotate.validate(new Annotator() { //validate annotations + annotate.validate(new Worker() { //validate annotations @Override - public void enterAnnotation() { + public void run() { JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); try { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index e241739a46d..3d7bc38d049 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -88,33 +88,33 @@ public class Annotate { private int enterCount = 0; - ListBuffer q = new ListBuffer(); - ListBuffer typesQ = new ListBuffer(); - ListBuffer repeatedQ = new ListBuffer(); - ListBuffer afterRepeatedQ = new ListBuffer(); - ListBuffer validateQ = new ListBuffer(); + ListBuffer q = new ListBuffer(); + ListBuffer typesQ = new ListBuffer(); + ListBuffer repeatedQ = new ListBuffer(); + ListBuffer afterRepeatedQ = new ListBuffer(); + ListBuffer validateQ = new ListBuffer(); - public void earlier(Annotator a) { + public void earlier(Worker a) { q.prepend(a); } - public void normal(Annotator a) { + public void normal(Worker a) { q.append(a); } - public void typeAnnotation(Annotator a) { + public void typeAnnotation(Worker a) { typesQ.append(a); } - public void repeated(Annotator a) { + public void repeated(Worker a) { repeatedQ.append(a); } - public void afterRepeated(Annotator a) { + public void afterRepeated(Worker a) { afterRepeatedQ.append(a); } - public void validate(Annotator a) { + public void validate(Worker a) { validateQ.append(a); } @@ -134,32 +134,34 @@ public class Annotate { enterCount++; try { while (q.nonEmpty()) { - q.next().enterAnnotation(); + q.next().run(); } while (typesQ.nonEmpty()) { - typesQ.next().enterAnnotation(); + typesQ.next().run(); } while (repeatedQ.nonEmpty()) { - repeatedQ.next().enterAnnotation(); + repeatedQ.next().run(); } while (afterRepeatedQ.nonEmpty()) { - afterRepeatedQ.next().enterAnnotation(); + afterRepeatedQ.next().run(); } while (validateQ.nonEmpty()) { - validateQ.next().enterAnnotation(); + validateQ.next().run(); } } finally { enterCount--; } } - /** A client that has annotations to add registers an annotator, - * the method it will use to add the annotation. There are no - * parameters; any needed data should be captured by the - * Annotator. + /** A client that needs to run during {@link #flush()} registers an worker + * into one of the queues defined in this class. The queues are: {@link #earlier(Worker)}, + * {@link #normal(Worker)}, {@link #typeAnnotation(Worker)}, {@link #repeated(Worker)}, + * {@link #afterRepeated(Worker)}, {@link #validate(Worker)}. + * The {@link Worker#run()} method will called inside the {@link #flush()} + * call. Queues are empties in the abovementioned order. */ - public interface Annotator { - void enterAnnotation(); + public interface Worker { + void run(); String toString(); } @@ -204,12 +206,12 @@ public class Annotate { } /** - * Queue the Annotator a on the repeating annotations queue of the + * Queue the Worker a on the repeating annotations queue of the * Annotate instance this context belongs to. * - * @param a the Annotator to enqueue for repeating annotation annotating + * @param a the Worker to enqueue for repeating annotation annotating */ - public void annotateRepeated(Annotator a) { + public void annotateRepeated(Worker a) { Annotate.this.repeated(a); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 92e061600ce..bad247dfd99 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -4085,13 +4085,13 @@ public class Attr extends JCTree.Visitor { public void annotateType(final AnnotatedType type, final List annotations) { if (annotations.isEmpty()) return; - annotate.typeAnnotation(new Annotate.Annotator() { + annotate.typeAnnotation(new Annotate.Worker() { @Override public String toString() { return "annotate " + annotations + " onto " + type; } @Override - public void enterAnnotation() { + public void run() { List compounds = fromAnnotations(annotations); type.typeAnnotations = compounds; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 29e210a1b87..ce865333873 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -202,7 +202,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { }.importFrom(tsym); // enter non-types before annotations that might use them - annotate.earlier(new Annotate.Annotator() { + annotate.earlier(new Annotate.Worker() { Set processed = new HashSet(); public String toString() { @@ -228,7 +228,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } } - public void enterAnnotation() { + public void run() { importFrom(tsym); } }); @@ -296,7 +296,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { }.importFrom(tsym); // enter non-types before annotations that might use them - annotate.earlier(new Annotate.Annotator() { + annotate.earlier(new Annotate.Worker() { Set processed = new HashSet(); boolean found = false; @@ -326,7 +326,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } } - public void enterAnnotation() { + public void run() { JavaFileObject prev = log.useSource(env.toplevel.sourcefile); try { importFrom(tsym); @@ -841,14 +841,14 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (s.kind != PCK) { s.resetAnnotations(); // mark Annotations as incomplete for now } - annotate.normal(new Annotate.Annotator() { + annotate.normal(new Annotate.Worker() { @Override public String toString() { return "annotate " + annotations + " onto " + s + " in " + s.owner; } @Override - public void enterAnnotation() { + public void run() { Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); DiagnosticPosition prevLintPos = @@ -872,9 +872,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } }); - annotate.validate(new Annotate.Annotator() { //validate annotations + annotate.validate(new Annotate.Worker() { //validate annotations @Override - public void enterAnnotation() { + public void run() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { chk.validateAnnotations(annotations, s); @@ -946,7 +946,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { void annotateDefaultValueLater(final JCExpression defaultValue, final Env localEnv, final MethodSymbol m) { - annotate.normal(new Annotate.Annotator() { + annotate.normal(new Annotate.Worker() { @Override public String toString() { return "annotate " + m.owner + "." + @@ -954,7 +954,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } @Override - public void enterAnnotation() { + public void run() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { enterDefaultValue(defaultValue, localEnv, m); @@ -963,9 +963,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } }); - annotate.validate(new Annotate.Annotator() { //validate annotations + annotate.validate(new Annotate.Worker() { //validate annotations @Override - public void enterAnnotation() { + public void run() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { // if default value is an annotation, check it is a well-formed @@ -1264,13 +1264,13 @@ public class MemberEnter extends JCTree.Visitor implements Completer { final DiagnosticPosition deferPos = this.deferPos; - annotate.normal(new Annotate.Annotator() { + annotate.normal(new Annotate.Worker() { @Override public String toString() { return "type annotate " + annotations + " onto " + sym + " in " + sym.owner; } @Override - public void enterAnnotation() { + public void run() { JavaFileObject prev = log.useSource(env.toplevel.sourcefile); DiagnosticPosition prevLintPos = null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 8b3ee47bf70..c172bb396d5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1877,7 +1877,7 @@ public class ClassReader { } } - class AnnotationDefaultCompleter extends AnnotationDeproxy implements Annotate.Annotator { + class AnnotationDefaultCompleter extends AnnotationDeproxy implements Annotate.Worker { final MethodSymbol sym; final Attribute value; final JavaFileObject classFile = currentClassFile; @@ -1889,8 +1889,8 @@ public class ClassReader { this.sym = sym; this.value = value; } - // implement Annotate.Annotator.enterAnnotation() - public void enterAnnotation() { + // implement Annotate.Worker.run() + public void run() { JavaFileObject previousClassFile = currentClassFile; try { // Reset the interim value set earlier in @@ -1904,7 +1904,7 @@ public class ClassReader { } } - class AnnotationCompleter extends AnnotationDeproxy implements Annotate.Annotator { + class AnnotationCompleter extends AnnotationDeproxy implements Annotate.Worker { final Symbol sym; final List l; final JavaFileObject classFile; @@ -1917,8 +1917,8 @@ public class ClassReader { this.l = l; this.classFile = currentClassFile; } - // implement Annotate.Annotator.enterAnnotation() - public void enterAnnotation() { + // implement Annotate.Worker.run() + public void run() { JavaFileObject previousClassFile = currentClassFile; try { currentClassFile = classFile; @@ -1955,7 +1955,7 @@ public class ClassReader { } @Override - public void enterAnnotation() { + public void run() { JavaFileObject previousClassFile = currentClassFile; try { currentClassFile = classFile; From e5c34a89eb01a313387e54565fa5155236c586cd Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Tue, 15 Oct 2013 15:57:13 -0700 Subject: [PATCH 101/152] 8026564: import changes from type-annotations forest Co-authored-by: Steve Sides Reviewed-by: jjg --- langtools/make/build.properties | 4 +- langtools/make/build.xml | 2 +- .../com/sun/tools/javac/code/Attribute.java | 3 +- .../com/sun/tools/javac/code/Printer.java | 19 +- .../sun/tools/javac/code/SymbolMetadata.java | 2 +- .../com/sun/tools/javac/code/Type.java | 26 +-- .../sun/tools/javac/code/TypeAnnotations.java | 87 ++++---- .../com/sun/tools/javac/code/Types.java | 10 +- .../com/sun/tools/javac/comp/Annotate.java | 3 +- .../com/sun/tools/javac/comp/Attr.java | 174 +++++++++------ .../com/sun/tools/javac/comp/Check.java | 5 +- .../com/sun/tools/javac/comp/Lower.java | 17 +- .../tools/javac/resources/compiler.properties | 11 +- .../com/sun/tools/javac/tree/JCTree.java | 1 + .../javax/lang/model/AnnotatedConstruct.java | 4 +- .../TestTypeAnnotations.java | 1 + .../typeAnnotations/smoke/TestSmoke.java | 1 + langtools/test/tools/javac/T7042623.java | 1 + .../classfile/ClassfileTestHelper.java | 10 +- .../typeAnnotations/classfile/Scopes.java | 59 +++++ .../failures/AnnotatedImport.java | 3 + .../failures/AnnotatedPackage1.java | 4 + .../failures/AnnotatedPackage1.out | 2 +- .../failures/AnnotatedPackage2.java | 3 + .../failures/AnnotationVersion.java | 8 +- .../failures/AnnotationVersion.out | 2 +- .../failures/AnnotationVersion7.out | 2 +- .../typeAnnotations/failures/BadCast.java | 3 + .../typeAnnotations/failures/BadCast.out | 4 +- .../failures/CantAnnotatePackages.java | 27 +++ .../failures/CantAnnotatePackages.out | 5 + .../failures/CantAnnotateScoping.java | 71 ++++++ .../failures/CantAnnotateScoping.out | 11 + .../failures/CantAnnotateStaticClass.java | 103 +++++++-- .../failures/CantAnnotateStaticClass.out | 10 - .../failures/CantAnnotateStaticClass2.java | 207 ++++++++++++++++++ .../failures/CantAnnotateStaticClass2.out | 65 ++++++ .../failures/CantAnnotateStaticClass3.java | 207 ++++++++++++++++++ .../failures/CantAnnotateStaticClass3.out | 83 +++++++ .../failures/IncompleteArray.java | 3 + .../failures/IncompleteArray.out | 2 +- .../failures/IncompleteVararg.java | 13 -- .../failures/IncompleteVararg.out | 2 - .../typeAnnotations/failures/IndexArray.java | 3 + .../typeAnnotations/failures/IndexArray.out | 2 +- .../typeAnnotations/failures/LintCast.out | 6 +- .../typeAnnotations/failures/OldArray.java | 29 +-- .../typeAnnotations/failures/OldArray.out | 10 + .../typeAnnotations/failures/Scopes.java | 19 +- .../typeAnnotations/failures/Scopes.out | 7 +- .../failures/StaticFields.java | 16 +- .../typeAnnotations/failures/StaticFields.out | 7 +- .../failures/StaticMethods.java | 12 - .../failures/StaticMethods.out | 2 - .../failures/TypeVariableCycleTest.java | 6 +- .../failures/TypeVariableMissingTA.java | 39 ++++ .../failures/TypeVariableMissingTA.out | 2 + ...ticClass.java => CantAnnotateScoping.java} | 16 +- ...tedType.java => CantAnnotateScoping1.java} | 10 +- langtools/test/tools/javac/lib/DPrinter.java | 4 +- .../processing/model/type/BasicAnnoTests.java | 1 + 61 files changed, 1173 insertions(+), 298 deletions(-) create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/classfile/Scopes.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out delete mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.out create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.out delete mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java delete mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out delete mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java delete mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.java create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.out rename langtools/test/tools/javac/diags/examples/{CantAnnotateStaticClass.java => CantAnnotateScoping.java} (82%) rename langtools/test/tools/javac/diags/examples/{CantAnnotateNestedType.java => CantAnnotateScoping1.java} (89%) diff --git a/langtools/make/build.properties b/langtools/make/build.properties index d16be20b724..ee7251738ed 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -163,11 +163,11 @@ javap.tests = \ # sjavac.includes = \ - com/sun/tools/sjavac/ + com/sun/tools/sjavac/ sjavac.tests = \ tools/sjavac - + # # The following files require the latest JDK to be available. diff --git a/langtools/make/build.xml b/langtools/make/build.xml index ddd0bc44bfe..b612a22715e 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -89,7 +89,7 @@ build-classes-TOOL build the classes for the tool build-TOOL build the jar file and script for the tool jtreg-TOOL build the tool and run the appropriate tests - findbugs-TOOL run findbugs on the tool's source oode + findbugs-TOOL run findbugs on the tool's source code TOOL build the tool, run the tests, and run findbugs - utility definitions --> diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java index 7f45ee6e57b..ec2cd4e1719 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java @@ -236,6 +236,7 @@ public abstract class Attribute implements AnnotationValue { public static class TypeCompound extends Compound { public TypeAnnotationPosition position; + public TypeCompound(Compound compound, TypeAnnotationPosition position) { this(compound.type, compound.values, position); @@ -256,7 +257,7 @@ public abstract class Attribute implements AnnotationValue { } public boolean hasUnknownPosition() { - return position == null || position.type == TargetType.UNKNOWN; + return position.type == TargetType.UNKNOWN; } public boolean isContainerTypeCompound() { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java index d46631504b2..03019926c08 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java @@ -260,24 +260,23 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi @Override public String visitAnnotatedType(AnnotatedType t, Locale locale) { - if (t.typeAnnotations != null && - t.typeAnnotations.nonEmpty()) { - if (t.underlyingType.hasTag(TypeTag.ARRAY)) { + if (t.getAnnotationMirrors().nonEmpty()) { + if (t.unannotatedType().hasTag(TypeTag.ARRAY)) { StringBuilder res = new StringBuilder(); printBaseElementType(t, res, locale); printBrackets(t, res, locale); return res.toString(); - } else if (t.underlyingType.hasTag(TypeTag.CLASS) && - t.underlyingType.getEnclosingType() != Type.noType) { - return visit(t.underlyingType.getEnclosingType(), locale) + + } else if (t.unannotatedType().hasTag(TypeTag.CLASS) && + t.unannotatedType().getEnclosingType() != Type.noType) { + return visit(t.unannotatedType().getEnclosingType(), locale) + ". " + - t.typeAnnotations + - " " + className((ClassType)t.underlyingType, false, locale); + t.getAnnotationMirrors() + + " " + className((ClassType)t.unannotatedType(), false, locale); } else { - return t.typeAnnotations + " " + visit(t.underlyingType, locale); + return t.getAnnotationMirrors() + " " + visit(t.unannotatedType(), locale); } } else { - return visit(t.underlyingType, locale); + return visit(t.unannotatedType(), locale); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java index 46d162b71fa..303dacd9e39 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java @@ -429,7 +429,7 @@ public class SymbolMetadata { super(on.type, List.>nil(), ctx.isTypeCompound ? ((Attribute.TypeCompound)placeholderFor.head).position : - null); + new TypeAnnotationPosition()); this.ctx = ctx; this.placeholderFor = placeholderFor; this.on = on; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index 82e9be2be3e..58bb0f18e72 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -225,6 +225,10 @@ public abstract class Type extends AnnoConstruct implements TypeMirror { return this; } + public Type annotatedType(List annos) { + return new AnnotatedType(annos, this); + } + public boolean isAnnotated() { return false; } @@ -1818,25 +1822,19 @@ public abstract class Type extends AnnoConstruct implements TypeMirror { javax.lang.model.type.WildcardType { /** The type annotations on this type. */ - public List typeAnnotations; + private List typeAnnotations; /** The underlying type that is annotated. */ - public Type underlyingType; + private Type underlyingType; - public AnnotatedType(Type underlyingType) { - super(underlyingType.tsym); - this.typeAnnotations = List.nil(); - this.underlyingType = underlyingType; - Assert.check(!underlyingType.isAnnotated(), - "Can't annotate already annotated type: " + underlyingType); - } - - public AnnotatedType(List typeAnnotations, + protected AnnotatedType(List typeAnnotations, Type underlyingType) { super(underlyingType.tsym); this.typeAnnotations = typeAnnotations; this.underlyingType = underlyingType; + Assert.check(typeAnnotations != null && typeAnnotations.nonEmpty(), + "Can't create AnnotatedType without annotations: " + underlyingType); Assert.check(!underlyingType.isAnnotated(), "Can't annotate already annotated type: " + underlyingType + "; adding: " + typeAnnotations); @@ -1977,10 +1975,8 @@ public abstract class Type extends AnnoConstruct implements TypeMirror { public TypeMirror getComponentType() { return ((ArrayType)underlyingType).getComponentType(); } // The result is an ArrayType, but only in the model sense, not the Type sense. - public AnnotatedType makeVarargs() { - AnnotatedType atype = new AnnotatedType(((ArrayType)underlyingType).makeVarargs()); - atype.typeAnnotations = this.typeAnnotations; - return atype; + public Type makeVarargs() { + return ((ArrayType) underlyingType).makeVarargs().annotatedType(typeAnnotations); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index cda3c0fa444..909ec875d79 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -290,6 +290,7 @@ public class TypeAnnotations { List annotations = sym.getRawAttributes(); ListBuffer declAnnos = new ListBuffer(); ListBuffer typeAnnos = new ListBuffer(); + ListBuffer onlyTypeAnnos = new ListBuffer(); for (Attribute.Compound a : annotations) { switch (annotationType(a, sym)) { @@ -305,6 +306,8 @@ public class TypeAnnotations { case TYPE: { Attribute.TypeCompound ta = toTypeCompound(a, pos); typeAnnos.append(ta); + // Also keep track which annotations are only type annotations + onlyTypeAnnos.append(ta); break; } } @@ -328,7 +331,7 @@ public class TypeAnnotations { } // type is non-null and annotations are added to that type - type = typeWithAnnotations(typetree, type, typeAnnotations); + type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList()); if (sym.getKind() == ElementKind.METHOD) { sym.type.asMethodType().restype = type; @@ -380,32 +383,23 @@ public class TypeAnnotations { // As a side effect the method sets the type annotation position of "annotations". // Note that it is assumed that all annotations share the same position. private Type typeWithAnnotations(final JCTree typetree, final Type type, - final List annotations) { - // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", - // typetree, type, annotations); + final List annotations, + final List onlyTypeAnnotations) { + // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n", + // typetree, type, annotations, onlyTypeAnnotations); if (annotations.isEmpty()) { return type; } if (type.hasTag(TypeTag.ARRAY)) { + Type.ArrayType arType = (Type.ArrayType) type.unannotatedType(); + Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym); Type toreturn; - Type.ArrayType tomodify; - Type.ArrayType arType; - { - Type touse = type; - if (type.isAnnotated()) { - Type.AnnotatedType atype = (Type.AnnotatedType)type; - toreturn = new Type.AnnotatedType(atype.underlyingType); - ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations; - touse = atype.underlyingType; - arType = (Type.ArrayType) touse; - tomodify = new Type.ArrayType(null, arType.tsym); - ((Type.AnnotatedType)toreturn).underlyingType = tomodify; - } else { - arType = (Type.ArrayType) touse; - tomodify = new Type.ArrayType(null, arType.tsym); - toreturn = tomodify; - } + if (type.isAnnotated()) { + toreturn = tomodify.annotatedType(type.getAnnotationMirrors()); + } else { + toreturn = tomodify; } + JCArrayTypeTree arTree = arrayTypeTree(typetree); ListBuffer depth = new ListBuffer<>(); @@ -413,12 +407,10 @@ public class TypeAnnotations { while (arType.elemtype.hasTag(TypeTag.ARRAY)) { if (arType.elemtype.isAnnotated()) { Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype; - Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType); - tomodify.elemtype = newAT; - newAT.typeAnnotations = aelemtype.typeAnnotations; - arType = (Type.ArrayType) aelemtype.underlyingType; + arType = (Type.ArrayType) aelemtype.unannotatedType(); + ArrayType prevToMod = tomodify; tomodify = new Type.ArrayType(null, arType.tsym); - newAT.underlyingType = tomodify; + prevToMod.elemtype = (Type.AnnotatedType) tomodify.annotatedType(arType.elemtype.getAnnotationMirrors()); } else { arType = (Type.ArrayType) arType.elemtype; tomodify.elemtype = new Type.ArrayType(null, arType.tsym); @@ -427,7 +419,7 @@ public class TypeAnnotations { arTree = arrayTypeTree(arTree.elemtype); depth = depth.append(TypePathEntry.ARRAY); } - Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations); + Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, onlyTypeAnnotations); tomodify.elemtype = arelemType; { // All annotations share the same position; modify the first one. @@ -444,7 +436,7 @@ public class TypeAnnotations { // There is a TypeKind, but no TypeTag. JCTypeUnion tutree = (JCTypeUnion) typetree; JCExpression fst = tutree.alternatives.get(0); - Type res = typeWithAnnotations(fst, fst.type, annotations); + Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations); fst.type = res; // TODO: do we want to set res as first element in uct.alternatives? // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type; @@ -483,14 +475,23 @@ public class TypeAnnotations { * but nothing more exists. */ if (enclTy != null && - enclTy.getKind() == TypeKind.NONE && - (enclTr.getKind() == JCTree.Kind.IDENTIFIER || - enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || - enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || - enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { - // TODO: also if it's "java. @A lang.Object", that is, - // if it's on a package? - log.error(enclTr.pos(), "cant.annotate.nested.type", enclTr.toString()); + enclTy.hasTag(TypeTag.NONE)) { + switch (onlyTypeAnnotations.size()) { + case 0: + // Don't issue an error if all type annotations are + // also declaration annotations. + // If the annotations are also declaration annotations, they are + // illegal as type annotations but might be legal as declaration annotations. + // The normal declaration annotation checks make sure that the use is valid. + break; + case 1: + log.error(typetree.pos(), "cant.type.annotate.scoping.1", + onlyTypeAnnotations); + break; + default: + log.error(typetree.pos(), "cant.type.annotate.scoping", + onlyTypeAnnotations); + } return type; } @@ -569,7 +570,7 @@ public class TypeAnnotations { // assert that t.constValue() == null? if (t == stopAt || t.getEnclosingType() == Type.noType) { - return new AnnotatedType(s, t); + return t.annotatedType(s); } else { ClassType ret = new ClassType(t.getEnclosingType().accept(this, s), t.typarams_field, t.tsym); @@ -584,12 +585,12 @@ public class TypeAnnotations { @Override public Type visitAnnotatedType(AnnotatedType t, List s) { - return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s)); + return t.unannotatedType().accept(this, s).annotatedType(t.getAnnotationMirrors()); } @Override public Type visitWildcardType(WildcardType t, List s) { - return new AnnotatedType(s, t); + return t.annotatedType(s); } @Override @@ -612,12 +613,12 @@ public class TypeAnnotations { @Override public Type visitTypeVar(TypeVar t, List s) { - return new AnnotatedType(s, t); + return t.annotatedType(s); } @Override public Type visitCapturedType(CapturedType t, List s) { - return new AnnotatedType(s, t); + return t.annotatedType(s); } @Override @@ -634,12 +635,12 @@ public class TypeAnnotations { @Override public Type visitErrorType(ErrorType t, List s) { - return new AnnotatedType(s, t); + return t.annotatedType(s); } @Override public Type visitType(Type t, List s) { - return new AnnotatedType(s, t); + return t.annotatedType(s); } }; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index b5c512e652d..c214bf16859 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -1273,7 +1273,7 @@ public class Types { return false; if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors())) return false; - return visit(t.underlyingType, s); + return visit(t.unannotatedType(), s); } }; // @@ -2217,15 +2217,15 @@ public class Types { @Override public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { - Type erased = erasure(t.underlyingType, recurse); + Type erased = erasure(t.unannotatedType(), recurse); if (erased.isAnnotated()) { // This can only happen when the underlying type is a // type variable and the upper bound of it is annotated. // The annotation on the type variable overrides the one // on the bound. - erased = ((AnnotatedType)erased).underlyingType; + erased = ((AnnotatedType)erased).unannotatedType(); } - return new AnnotatedType(t.typeAnnotations, erased); + return erased.annotatedType(t.getAnnotationMirrors()); } }; @@ -4419,7 +4419,7 @@ public class Types { public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } // Pretend annotations don't exist - public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); } + public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.unannotatedType(), s); } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index 3d7bc38d049..5fe4d3ba121 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -250,7 +250,8 @@ public class Annotate { a.type = chk.checkType(a.annotationType.pos(), at, expected); if (a.type.isErroneous()) { if (typeAnnotation) { - return new Attribute.TypeCompound(a.type, List.>nil(), null); + return new Attribute.TypeCompound(a.type, List.>nil(), + new TypeAnnotationPosition()); } else { return new Attribute.Compound(a.type, List.>nil()); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index bad247dfd99..458c16caacd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -3534,15 +3534,6 @@ public class Attr extends JCTree.Visitor { Type normOuter = site; if (normOuter.hasTag(CLASS)) { normOuter = types.asEnclosingSuper(site, ownOuter.tsym); - if (site.isAnnotated()) { - // Propagate any type annotations. - // TODO: should asEnclosingSuper do this? - // Note that the type annotations in site will be updated - // by annotateType. Therefore, modify site instead - // of creating a new AnnotatedType. - ((AnnotatedType)site).underlyingType = normOuter; - normOuter = site; - } } if (normOuter == null) // perhaps from an import normOuter = types.erasure(ownOuter); @@ -3901,12 +3892,6 @@ public class Attr extends JCTree.Visitor { } } owntype = new ClassType(clazzOuter, actuals, clazztype.tsym); - if (clazztype.isAnnotated()) { - // Use the same AnnotatedType, because it will have - // its annotations set later. - ((AnnotatedType)clazztype).underlyingType = owntype; - owntype = clazztype; - } } else { if (formals.length() != 0) { log.error(tree.pos(), "wrong.number.type.args", @@ -3972,9 +3957,7 @@ public class Attr extends JCTree.Visitor { TypeVar typeVar = (TypeVar) tree.type; if (tree.annotations != null && tree.annotations.nonEmpty()) { - AnnotatedType antype = new AnnotatedType(typeVar); - annotateType(antype, tree.annotations); - tree.type = antype; + annotateType(tree, tree.annotations); } if (!typeVar.bound.isErroneous()) { @@ -4074,26 +4057,28 @@ public class Attr extends JCTree.Visitor { public void visitAnnotatedType(JCAnnotatedType tree) { Type underlyingType = attribType(tree.getUnderlyingType(), env); this.attribAnnotationTypes(tree.annotations, env); - AnnotatedType antype = new AnnotatedType(underlyingType); - annotateType(antype, tree.annotations); - result = tree.type = antype; + annotateType(tree, tree.annotations); + result = tree.type = underlyingType; } /** * Apply the annotations to the particular type. */ - public void annotateType(final AnnotatedType type, final List annotations) { - if (annotations.isEmpty()) - return; + public void annotateType(final JCTree tree, final List annotations) { + // Callers ensure this. + // Assert.check(annotations != null && annotations.nonEmpty()); annotate.typeAnnotation(new Annotate.Worker() { @Override public String toString() { - return "annotate " + annotations + " onto " + type; + return "annotate " + annotations + " onto " + tree; } @Override public void run() { List compounds = fromAnnotations(annotations); - type.typeAnnotations = compounds; + if (annotations.size() == compounds.size()) { + // All annotations were successfully converted into compounds + tree.type = tree.type.unannotatedType().annotatedType(compounds); + } } }); } @@ -4432,18 +4417,19 @@ public class Attr extends JCTree.Visitor { private final class TypeAnnotationsValidator extends TreeScanner { private final boolean sigOnly; - private boolean checkAllAnnotations = false; - public TypeAnnotationsValidator(boolean sigOnly) { this.sigOnly = sigOnly; } public void visitAnnotation(JCAnnotation tree) { - if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) { - chk.validateTypeAnnotation(tree, false); - } + chk.validateTypeAnnotation(tree, false); super.visitAnnotation(tree); } + public void visitAnnotatedType(JCAnnotatedType tree) { + if (!tree.underlyingType.type.isErroneous()) { + super.visitAnnotatedType(tree); + } + } public void visitTypeParameter(JCTypeParameter tree) { chk.validateTypeAnnotations(tree.annotations, true); scan(tree.bounds); @@ -4475,7 +4461,7 @@ public class Attr extends JCTree.Visitor { } public void visitVarDef(final JCVariableDecl tree) { if (tree.sym != null && tree.sym.type != null) - validateAnnotatedType(tree, tree.sym.type); + validateAnnotatedType(tree.vartype, tree.sym.type); scan(tree.mods); scan(tree.vartype); if (!sigOnly) { @@ -4493,27 +4479,13 @@ public class Attr extends JCTree.Visitor { super.visitTypeTest(tree); } public void visitNewClass(JCNewClass tree) { - if (tree.clazz.hasTag(ANNOTATED_TYPE)) { - boolean prevCheck = this.checkAllAnnotations; - try { - this.checkAllAnnotations = true; - scan(((JCAnnotatedType)tree.clazz).annotations); - } finally { - this.checkAllAnnotations = prevCheck; - } - } + if (tree.clazz.type != null) + validateAnnotatedType(tree.clazz, tree.clazz.type); super.visitNewClass(tree); } public void visitNewArray(JCNewArray tree) { - if (tree.elemtype != null && tree.elemtype.hasTag(ANNOTATED_TYPE)) { - boolean prevCheck = this.checkAllAnnotations; - try { - this.checkAllAnnotations = true; - scan(((JCAnnotatedType)tree.elemtype).annotations); - } finally { - this.checkAllAnnotations = prevCheck; - } - } + if (tree.elemtype != null && tree.elemtype.type != null) + validateAnnotatedType(tree.elemtype, tree.elemtype.type); super.visitNewArray(tree); } @@ -4549,21 +4521,95 @@ public class Attr extends JCTree.Visitor { * can occur. */ private void validateAnnotatedType(final JCTree errtree, final Type type) { - if (type.getEnclosingType() != null && - type != type.getEnclosingType()) { - validateEnclosingAnnotatedType(errtree, type.getEnclosingType()); + // System.out.println("Attr.validateAnnotatedType: " + errtree + " type: " + type); + + if (type.isPrimitiveOrVoid()) { + return; } - for (Type targ : type.getTypeArguments()) { - validateAnnotatedType(errtree, targ); - } - } - private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) { - validateAnnotatedType(errtree, type); - if (type.tsym != null && - type.tsym.isStatic() && - type.getAnnotationMirrors().nonEmpty()) { - // Enclosing static classes cannot have type annotations. - log.error(errtree.pos(), "cant.annotate.static.class"); + + JCTree enclTr = errtree; + Type enclTy = type; + + boolean repeat = true; + while (repeat) { + if (enclTr.hasTag(TYPEAPPLY)) { + List tyargs = enclTy.getTypeArguments(); + List trargs = ((JCTypeApply)enclTr).getTypeArguments(); + if (trargs.length() > 0) { + // Nothing to do for diamonds + if (tyargs.length() == trargs.length()) { + for (int i = 0; i < tyargs.length(); ++i) { + validateAnnotatedType(trargs.get(i), tyargs.get(i)); + } + } + // If the lengths don't match, it's either a diamond + // or some nested type that redundantly provides + // type arguments in the tree. + } + + // Look at the clazz part of a generic type + enclTr = ((JCTree.JCTypeApply)enclTr).clazz; + } + + if (enclTr.hasTag(SELECT)) { + enclTr = ((JCTree.JCFieldAccess)enclTr).getExpression(); + if (enclTy != null && + !enclTy.hasTag(NONE)) { + enclTy = enclTy.getEnclosingType(); + } + } else if (enclTr.hasTag(ANNOTATED_TYPE)) { + JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr; + if (enclTy == null || + enclTy.hasTag(NONE)) { + if (at.getAnnotations().size() == 1) { + log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute); + } else { + ListBuffer comps = new ListBuffer(); + for (JCAnnotation an : at.getAnnotations()) { + comps.add(an.attribute); + } + log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList()); + } + repeat = false; + } + enclTr = at.underlyingType; + // enclTy doesn't need to be changed + } else if (enclTr.hasTag(IDENT)) { + repeat = false; + } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) { + JCWildcard wc = (JCWildcard) enclTr; + if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) { + validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy.unannotatedType()).getExtendsBound()); + } else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) { + validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy.unannotatedType()).getSuperBound()); + } else { + // Nothing to do for UNBOUND + } + repeat = false; + } else if (enclTr.hasTag(TYPEARRAY)) { + JCArrayTypeTree art = (JCArrayTypeTree) enclTr; + validateAnnotatedType(art.getType(), ((ArrayType)enclTy.unannotatedType()).getComponentType()); + repeat = false; + } else if (enclTr.hasTag(TYPEUNION)) { + JCTypeUnion ut = (JCTypeUnion) enclTr; + for (JCTree t : ut.getTypeAlternatives()) { + validateAnnotatedType(t, t.type); + } + repeat = false; + } else if (enclTr.hasTag(TYPEINTERSECTION)) { + JCTypeIntersection it = (JCTypeIntersection) enclTr; + for (JCTree t : it.getBounds()) { + validateAnnotatedType(t, t.type); + } + repeat = false; + } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE) { + // This happens in test TargetTypeTest52.java + // Is there anything to do? + repeat = false; + } else { + Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() + + " within: "+ errtree + " with kind: " + errtree.getKind()); + } } } }; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index c19cdb9ced3..073bbbc9c66 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -2769,8 +2769,11 @@ public class Check { Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a); validateAnnotationTree(a); - if (!isTypeAnnotation(a, isTypeParameter)) + if (a.hasTag(TYPE_ANNOTATION) && + !a.annotationType.type.isErroneous() && + !isTypeAnnotation(a, isTypeParameter)) { log.error(a.pos(), "annotation.type.not.applicable"); + } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index c362c77b15a..3731f0df226 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2834,20 +2834,9 @@ public class Lower extends TreeTranslator { tree.underlyingType = translate(tree.underlyingType); // but maintain type annotations in the type. if (tree.type.isAnnotated()) { - if (tree.underlyingType.type.isAnnotated()) { - // The erasure of a type variable might be annotated. - // Merge all annotations. - AnnotatedType newat = (AnnotatedType) tree.underlyingType.type; - AnnotatedType at = (AnnotatedType) tree.type; - at.underlyingType = newat.underlyingType; - newat.typeAnnotations = at.typeAnnotations.appendList(newat.typeAnnotations); - tree.type = newat; - } else { - // Create a new AnnotatedType to have the correct tag. - AnnotatedType oldat = (AnnotatedType) tree.type; - tree.type = new AnnotatedType(tree.underlyingType.type); - ((AnnotatedType) tree.type).typeAnnotations = oldat.typeAnnotations; - } + tree.type = tree.underlyingType.type.unannotatedType().annotatedType(tree.type.getAnnotationMirrors()); + } else if (tree.underlyingType.type.isAnnotated()) { + tree.type = tree.underlyingType.type; } result = tree; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 9e4701522ea..8874ec18bc7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -2257,13 +2257,14 @@ compiler.err.receiver.parameter.not.applicable.constructor.toplevel.class=\ receiver parameter not applicable for constructor of top-level class # TODO 308: make a better error message -compiler.err.cant.annotate.static.class=\ - enclosing static nested class cannot be annotated +# 0: symbol +compiler.err.cant.type.annotate.scoping.1=\ + scoping construct cannot be annotated with type-use annotation: {0} # TODO 308: make a better error message -# 0: unused -compiler.err.cant.annotate.nested.type=\ - scoping construct for static nested type cannot be annotated +# 0: list of symbol +compiler.err.cant.type.annotate.scoping=\ + scoping construct cannot be annotated with type-use annotations: {0} # 0: type, 1: type compiler.err.incorrect.receiver.name=\ diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index d1d71080027..9bec1cc7cf5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -2359,6 +2359,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public JCExpression underlyingType; protected JCAnnotatedType(List annotations, JCExpression underlyingType) { + Assert.check(annotations != null && annotations.nonEmpty()); this.annotations = annotations; this.underlyingType = underlyingType; } diff --git a/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java index f02f5cdbbd0..a80a6eab7d1 100644 --- a/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java +++ b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java @@ -221,8 +221,8 @@ public interface AnnotatedConstruct { * type if present on this construct, else an empty array * * @see #getAnnotationMirrors() - * @see #getAnnotation(java.lang.Class) - * @see java.lang.reflect.AnnotatedElement#getAnnotationsByType + * @see #getAnnotation(Class) + * @see java.lang.reflect.AnnotatedElement#getAnnotationsByType(Class) * @see EnumConstantNotPresentException * @see AnnotationTypeMismatchException * @see IncompleteAnnotationException diff --git a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java index d1eb1179aee..0627c07fccd 100644 --- a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java +++ b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java @@ -27,6 +27,7 @@ * @summary Make sure that type annotations are displayed correctly * @author Bhavesh Patel * @library ../lib/ + * @ignore * @build JavadocTester TestTypeAnnotations * @run main TestTypeAnnotations */ diff --git a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java index f90c1963990..b2021bb4f95 100644 --- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java @@ -28,6 +28,7 @@ * * @author Mahmood Ali * @library ../../lib/ + * @ignore * @build JavadocTester * @build TestSmoke * @run main TestSmoke diff --git a/langtools/test/tools/javac/T7042623.java b/langtools/test/tools/javac/T7042623.java index 70811d4267d..0c4fc5b614d 100644 --- a/langtools/test/tools/javac/T7042623.java +++ b/langtools/test/tools/javac/T7042623.java @@ -2,6 +2,7 @@ * @test /nodynamiccopyright/ * @bug 7042623 * @summary Regression: javac silently crash when attributing non-existent annotation + * @ignore * @compile/fail/ref=T7042623.out -XDrawDiagnostics -XDdev T7042623.java */ diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java index 952b73c3177..22280b44109 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java @@ -36,7 +36,8 @@ public class ClassfileTestHelper { //Makes debugging much easier. Set to 'false' for less output. public Boolean verbose = true; - void println(String msg) { if(verbose) System.out.println(msg); } + void println(String msg) { if (verbose) System.out.println(msg); } + void print(String msg) { if (verbose) System.out.print(msg); } File writeTestFile(String fname, String source) throws IOException { File f = new File(fname); @@ -183,6 +184,13 @@ public class ClassfileTestHelper { (RuntimeTypeAnnotations_attribute)attr; println(testtype + ": " + name + ", " + annName + ": " + tAttr.annotations.length ); + if (tAttr.annotations.length > 0) { + for (int i = 0; i < tAttr.annotations.length; i++) { + println(" types:" + tAttr.annotations[i].position.type); + } + } else { + println(""); + } allt += tAttr.annotations.length; if (visible) tvisibles += tAttr.annotations.length; diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Scopes.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Scopes.java new file mode 100644 index 00000000000..0c036912f2e --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Scopes.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary Qualified inner type annotation accessible to the class. + */ + +@Scopes.UniqueInner +public class Scopes extends ClassfileTestHelper{ + public static void main(String[] args) throws Exception { + new Scopes().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 1; + expected_invisibles = 1; + + ClassFile cf = getClassFile("Scopes.class"); + test(cf); + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + @Target({ElementType.TYPE_USE}) + @interface UniqueInner { }; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java index db14aefee15..c7b38cc5974 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java @@ -3,13 +3,16 @@ * @bug 8006775 * @summary Import clauses cannot use annotations. * @author Werner Dietl + * @ignore * @compile/fail/ref=AnnotatedImport.out -XDrawDiagnostics AnnotatedImport.java */ +import java.lang.annotation.*; import java.@A util.List; import @A java.util.Map; import java.util.@A HashMap; class AnnotatedImport { } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java index 6b8b64a656f..4122fa11e5c 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java @@ -3,11 +3,15 @@ * @bug 8006775 * @summary Package declarations cannot use annotations. * @author Werner Dietl + * @ignore * @compile/fail/ref=AnnotatedPackage1.out -XDrawDiagnostics AnnotatedPackage1.java */ package name.@A p1.p2; +import java.lang.annotation.*; + class AnnotatedPackage1 { } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out index 66ae60f72f2..648af198629 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out @@ -1,3 +1,3 @@ AnnotatedPackage1.java:9:14: compiler.err.expected: token.identifier -AnnotatedPackage1.java:9:15: compiler.err.expected3: class, interface, enum +AnnotatedPackage1.java:9:16: compiler.err.expected3: class, interface, enum 2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java index 53eb5b142f3..493261e7e06 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java @@ -8,6 +8,9 @@ package @A p1.p2; +import java.lang.annotation.*; + class AnnotatedPackage2 { } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java index 9f80b2e9f28..c9cc7d48287 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java @@ -3,11 +3,13 @@ * @bug 6843077 8006775 * @summary test that only Java 8 allows type annotations * @author Mahmood Ali + * @compile AnnotationVersion.java * @compile/fail/ref=AnnotationVersion.out -XDrawDiagnostics -Xlint:-options -source 1.6 AnnotationVersion.java * @compile/fail/ref=AnnotationVersion7.out -XDrawDiagnostics -Xlint:-options -source 1.7 AnnotationVersion.java */ -class AnnotationVersion { - public void method(@A AnnotationVersion this) { } -} +import java.lang.annotation.*; +class myNumber { } + +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out index d836ff3532a..25196ba0c01 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out @@ -1,2 +1,2 @@ -AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.6 +AnnotationVersion.java:12:27: compiler.err.type.annotations.not.supported.in.source: 1.6 1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out index cb2fca3edce..b6687df1501 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out @@ -1,2 +1,2 @@ -AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.7 +AnnotationVersion.java:12:27: compiler.err.type.annotations.not.supported.in.source: 1.7 1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java index a24c323d746..c178fbc2a53 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java @@ -5,10 +5,13 @@ * @author Werner Dietl * @compile/fail/ref=BadCast.out -XDrawDiagnostics BadCast.java */ +import java.lang.annotation.*; + class BadCast { static void main() { Object o = (@A) ""; } } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out index f1b8bf04ca6..7e3cc5e9bd1 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out @@ -1,2 +1,2 @@ -BadCast.java:10:19: compiler.err.illegal.start.of.type -1 error \ No newline at end of file +BadCast.java:12:19: compiler.err.illegal.start.of.type +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java new file mode 100644 index 00000000000..ece666239db --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java @@ -0,0 +1,27 @@ +/* + * @test /nodynamiccopyright/ + * @bug 1234567 + * @summary The parts of a fully-qualified type can't be annotated. + * @author Werner Dietl + * @compile/fail/ref=CantAnnotatePackages.out -XDrawDiagnostics CantAnnotatePackages.java + */ + +import java.lang.annotation.*; +import java.util.List; + +class CantAnnotatePackages { + // Before a package component: + @TA java.lang.Object of1; + + // These result in a different error. + // TODO: should this be unified? + + List<@TA java.lang.Object> of2; + java. @TA lang.Object of3; + List of4; + + // TODO: also note the order of error messages. +} + +@Target(ElementType.TYPE_USE) +@interface TA { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out new file mode 100644 index 00000000000..574ceb64cfb --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out @@ -0,0 +1,5 @@ +CantAnnotatePackages.java:19:14: compiler.err.cant.resolve.location: kindname.class, java, , , (compiler.misc.location: kindname.class, CantAnnotatePackages, null) +CantAnnotatePackages.java:20:9: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotatePackages.java:21:14: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotatePackages.java:14:18: compiler.err.cant.type.annotate.scoping.1: @TA +4 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java new file mode 100644 index 00000000000..f0ca4134df2 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java @@ -0,0 +1,71 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006733 8006775 + * @summary Ensure behavior for nested types is correct. + * @author Werner Dietl + * @compile/fail/ref=CantAnnotateScoping.out -XDrawDiagnostics CantAnnotateScoping.java + */ + +import java.util.List; +import java.util.ArrayList; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE_USE}) +@interface TA {} +@Target({ElementType.TYPE_USE}) +@interface TA2 {} + +@Target({ElementType.FIELD}) +@interface DA {} +@Target({ElementType.FIELD}) +@interface DA2 {} + +@Target({ElementType.TYPE_USE, ElementType.FIELD}) +@interface DTA {} +@Target({ElementType.TYPE_USE, ElementType.FIELD}) +@interface DTA2 {} + +class Test { + static class Outer { + static class SInner {} + } + + // Legal + List li; + + // Illegal + @TA Outer.SInner osi; + // Illegal + List<@TA Outer.SInner> aloi; + // Illegal + Object o1 = new @TA @DA @TA2 Outer.SInner(); + // Illegal + Object o = new ArrayList<@TA @DA Outer.SInner>(); + + // Illegal: @TA is only a type-use annotation + @TA java.lang.Object f1; + + // Legal: @DA is only a declaration annotation + @DA java.lang.Object f2; + + // Legal: @DTA is both a type-use and declaration annotation + @DTA java.lang.Object f3; + + // Illegal: @TA and @TA2 are only type-use annotations + @DTA @DA @TA @DA2 @TA2 java.lang.Object f4; + + // Illegal: Do we want one or two messages? + // 1: @DA in invalid location + // 2: Not finding class "lang" + java. @DA lang.Object f5; + + // Illegal: Do we want one or two messages? + // 1: @DA in invalid location + // 2: Not finding class "XXX" + java. @DA XXX.Object f6; + + // Illegal: Can't find class "lang". + // Would a different error message be desirable? + java. @TA lang.Object f7; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out new file mode 100644 index 00000000000..d2144ab86b0 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out @@ -0,0 +1,11 @@ +CantAnnotateScoping.java:61:9: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotateScoping.java:66:9: compiler.err.cant.resolve.location: kindname.class, XXX, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotateScoping.java:70:9: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotateScoping.java:38:14: compiler.err.cant.type.annotate.scoping.1: @TA +CantAnnotateScoping.java:47:18: compiler.err.cant.type.annotate.scoping.1: @TA +CantAnnotateScoping.java:56:37: compiler.err.cant.type.annotate.scoping: @TA,@TA2 +CantAnnotateScoping.java:40:14: compiler.err.cant.type.annotate.scoping.1: @TA +CantAnnotateScoping.java:42:34: compiler.err.cant.type.annotate.scoping: @TA,@DA,@TA2 +CantAnnotateScoping.java:44:38: compiler.err.cant.type.annotate.scoping: @TA,@DA +CantAnnotateScoping.java:44:34: compiler.err.annotation.type.not.applicable +10 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java index 98a38e220da..cf019b117f5 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java @@ -1,41 +1,96 @@ /* * @test /nodynamiccopyright/ * @bug 8006733 8006775 - - * @summary A static outer class cannot be annotated. + * @summary Ensure behavior for nested types is correct. * @author Werner Dietl - * @compile/fail/ref=CantAnnotateStaticClass.out -XDrawDiagnostics CantAnnotateStaticClass.java + * @compile CantAnnotateStaticClass.java */ import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; import java.lang.annotation.*; -class CantAnnotateStaticClass { +class Top { @Target(ElementType.TYPE_USE) - @interface A {} + @interface TA {} - static class Outer { - class Inner {} + @Target(ElementType.TYPE_USE) + @interface TB {} + + @Target(ElementType.TYPE_USE) + @interface TC {} + + class Outer { + class Inner { + Object o1 = Top.this; + Object o2 = Outer.this; + Object o3 = this; + } + // Illegal + // static class SInner {} + // interface IInner {} } - // 8 errors: - @A Outer.Inner f1; - @A Outer.Inner f1r() { return null; } - void f1p(@A Outer.Inner p) { } - void f1c(Object o) { - Object l = (@A Outer.Inner) o; + // All combinations are OK + + Top.@TB Outer f1; + @TB Outer.Inner f1a; + Outer. @TC Inner f1b; + @TB Outer. @TC Inner f1c; + + @TA Top. @TB Outer f2; + @TA Top. @TB Outer.Inner f2a; + @TA Top. Outer. @TC Inner f2b; + @TA Top. @TB Outer. @TC Inner f2c; + + @TB Outer f1r() { return null; } + @TB Outer.Inner f1ra() { return null; } + Outer. @TC Inner f1rb() { return null; } + @TB Outer. @TC Inner f1rc() { return null; } + + void f1param(@TB Outer p, + @TB Outer.Inner p1, + Outer. @TC Inner p2, + @TB Outer. @TC Inner p3) { } + + void f1cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.Inner) o; + l = (Outer. @TC Inner) o; + l = (@TB Outer. @TC Inner) o; } - List<@A Outer.Inner> f2; - List<@A Outer.Inner> f2r() { return null; } - void f2p(List<@A Outer.Inner> p) { } - void f2c(Object o) { - Object l = (List<@A Outer.Inner>) o; - } + List<@TB Outer> g1; + List<@TB Outer.Inner> g1a; + List g1b; + List<@TB Outer. @TC Inner> g1c; - // OK: - @A Outer g1; - List<@A Outer> g2; - Outer. @A Inner g3; - List g4; + List<@TA Top. @TB Outer> g2; + List<@TA Top. @TB Outer.Inner> g2a; + List<@TA Top. Outer. @TC Inner> g2b; + List<@TA Top. @TB Outer. @TC Inner> g2c; + + List<@TB Outer> g1r() { return null; } + List<@TB Outer.Inner> g1ra() { return null; } + List g1rb() { return null; } + List<@TB Outer. @TC Inner> g1rc() { return null; } + + void g1param(List<@TB Outer> p, + List<@TB Outer.Inner> p1, + List p2, + List<@TB Outer. @TC Inner> p3) { } + + void g1new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.Inner>(); + l = new @TB HashMap(); + l = new @TB HashMap(); + l = new @TB HashMap(); + l = new @TB HashMap(); + l = new @TB HashMap(); + l = new @TB HashMap(); + } } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out deleted file mode 100644 index 585cc0aec4b..00000000000 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out +++ /dev/null @@ -1,10 +0,0 @@ -CantAnnotateStaticClass.java:22:20: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:23:13: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:24:29: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:29:26: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:30:9: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:31:35: compiler.err.cant.annotate.static.class -CantAnnotateStaticClass.java:26:29: compiler.err.cant.annotate.static.class -- compiler.note.unchecked.filename: CantAnnotateStaticClass.java -- compiler.note.unchecked.recompile -7 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.java new file mode 100644 index 00000000000..f53340f6366 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.java @@ -0,0 +1,207 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006733 8006775 + * @summary Ensure behavior for nested types is correct. + * @author Werner Dietl + * @ignore + * @compile/fail/ref=CantAnnotateStaticClass2.out -XDrawDiagnostics CantAnnotateStaticClass2.java + */ + +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.lang.annotation.*; + +class Top { + @Target(ElementType.TYPE_USE) + @interface TA {} + + @Target(ElementType.TYPE_USE) + @interface TB {} + + @Target(ElementType.TYPE_USE) + @interface TC {} + + static class Outer { + class Inner { + // Object o1 = Top.this; + Object o2 = Outer.this; + Object o3 = this; + } + static class SInner { + // Object o1 = Top.this; + // Object o2 = Outer.this; + Object o3 = this; + } + interface IInner { + // Object o1 = Top.this; + // Object o2 = Outer.this; + // Object o3 = this; + } + } + + @TB Outer f1; + @TB Outer.Inner f1a; + @TB Outer.SInner f2a; // err + @TB Outer.IInner f3a; // err + + Outer. @TC Inner f1b; + Outer. @TC SInner f2b; + Outer. @TC IInner f3b; + + @TB Outer. @TC Inner f1c; + @TB Outer. @TC SInner f2c; // err + @TB Outer. @TC IInner f3c; // err + + @TA Top. @TB Outer g1; // err + @TA Top. @TB Outer.Inner g1a; // err + @TA Top. @TB Outer.SInner g2a; // err + @TA Top. @TB Outer.IInner g3a; // err + + @TA Top. Outer. @TC Inner g1b; // err + @TA Top. Outer. @TC SInner g2b; // err + @TA Top. Outer. @TC IInner g3b; // err + + @TA Top. @TB Outer. @TC Inner g1c; // err + @TA Top. @TB Outer. @TC SInner g2c; // err + @TA Top. @TB Outer. @TC IInner g3c; // err + + @TB Outer f1r() { return null; } + + @TB Outer.Inner f1ra() { return null; } + @TB Outer.SInner f2ra() { return null; } // err + @TB Outer.IInner f3ra() { return null; } // err + + Outer. @TC Inner f1rb() { return null; } + Outer. @TC SInner f2rb() { return null; } + Outer. @TC IInner f3rb() { return null; } + + @TB Outer. @TC Inner f1rc() { return null; } + @TB Outer. @TC SInner f2rc() { return null; } // err + @TB Outer. @TC IInner f3rc() { return null; } // err + + void f1param(@TB Outer p, + @TB Outer.Inner p1, + Outer. @TC Inner p2, + @TB Outer. @TC Inner p3) { } + void f2param(@TB Outer p, + @TB Outer.SInner p1, // err + Outer. @TC SInner p2, + @TB Outer. @TC SInner p3) { } // err + void f3param(@TB Outer p, + @TB Outer.IInner p1, // err + Outer. @TC IInner p2, + @TB Outer. @TC IInner p3) { } // err + + void f1cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.Inner) o; + l = (Outer. @TC Inner) o; + l = (@TB Outer. @TC Inner) o; + } + void f2cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.SInner) o; // err + l = (Outer. @TC SInner) o; + l = (@TB Outer. @TC SInner) o; // err + } + void f3cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.IInner) o; // err + l = (Outer. @TC IInner) o; + l = (@TB Outer. @TC IInner) o; // err + } + + List<@TB Outer> h1; + + List<@TB Outer.Inner> h1a; + List<@TB Outer.SInner> h2a; // err + List<@TB Outer.IInner> h3a; // err + + List h1b; + List h2b; + List h3b; + + List<@TB Outer. @TC Inner> h1c; + List<@TB Outer. @TC SInner> h2c; // err + List<@TB Outer. @TC IInner> h3c; // err + + List<@TA Top. @TB Outer> k1; // err + + List<@TA Top. @TB Outer.Inner> k1a; // err + List<@TA Top. @TB Outer.SInner> k2a; // err + List<@TA Top. @TB Outer.IInner> k3a; // err + + List<@TA Top. Outer. @TC Inner> k1b; // err + List<@TA Top. Outer. @TC SInner> k2b; // err + List<@TA Top. Outer. @TC IInner> k3b; // err + + List<@TA Top. @TB Outer. @TC Inner> k1c; // err + List<@TA Top. @TB Outer. @TC SInner> k2c; // err + List<@TA Top. @TB Outer. @TC IInner> k3c; // err + + + List<@TB Outer> g1r() { return null; } + + List<@TB Outer.Inner> g1ra() { return null; } + List<@TB Outer.SInner> g2ra() { return null; } // err + List<@TB Outer.IInner> g3ra() { return null; } // err + + List g1rb() { return null; } + List g2rb() { return null; } + List g3rb() { return null; } + + List<@TB Outer. @TC Inner> g1rc() { return null; } + List<@TB Outer. @TC SInner> g2rc() { return null; } // err + List<@TB Outer. @TC IInner> g3rc() { return null; } // err + + void g1param(List<@TB Outer> p, + List<@TB Outer.Inner> p1, + List p2, + List<@TB Outer. @TC Inner> p3) { } + void g2param(List<@TB Outer> p, + List<@TB Outer.SInner> p1, // err + List p2, + List<@TB Outer. @TC SInner> p3) { } // err + void g3param(List<@TB Outer> p, + List<@TB Outer.IInner> p1, // err + List p2, + List<@TB Outer. @TC IInner> p3) { } // err + + void g1new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.Inner>(); + l = new @TB HashMap(); + l = new @TB HashMap(); + l = new @TB HashMap(); + } + void g2new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.SInner>(); // err + l = new @TB HashMap(); + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } + void g3new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.IInner>(); // err + l = new @TB HashMap(); + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } + void g4new(Object o) { + Object l; + l = new @TB ArrayList<@TA Top. @TB Outer>(); // err + l = new @TB ArrayList<@TA Top. @TB Outer.IInner>(); // err + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.out new file mode 100644 index 00000000000..977dd690624 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.out @@ -0,0 +1,65 @@ +CantAnnotateStaticClass2.java:44:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:45:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:52:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:53:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:55:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:56:23: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:57:23: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:58:23: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:60:21: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:61:21: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:62:21: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:64:25: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:65:25: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:66:25: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:71:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:72:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:79:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:80:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:87:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:89:24: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:91:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:93:24: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:57:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:58:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:65:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:66:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:105:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:107:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:112:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:114:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:120:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:121:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:128:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:129:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:131:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:133:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:134:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:135:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:137:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:138:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:139:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:141:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:142:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:143:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:149:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:150:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:157:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:158:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:165:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:167:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:169:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:171:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:184:35: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:186:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:187:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:192:35: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:194:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:195:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:199:35: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:200:38: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:201:41: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass2.java:202:44: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:203:44: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass2.java:204:49: compiler.err.cant.type.annotate.scoping: @Top.TA,@Top.TB,@Top.TC +64 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.java new file mode 100644 index 00000000000..f9d123e91b5 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.java @@ -0,0 +1,207 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006733 8006775 + * @summary Ensure behavior for nested types is correct. + * @author Werner Dietl + * @ignore + * @compile/fail/ref=CantAnnotateStaticClass3.out -XDrawDiagnostics CantAnnotateStaticClass3.java + */ + +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.lang.annotation.*; + +class Top { + @Target(ElementType.TYPE_USE) + @interface TA {} + + @Target(ElementType.TYPE_USE) + @interface TB {} + + @Target(ElementType.TYPE_USE) + @interface TC {} + + interface Outer { + class Inner { + // Object o1 = Top.this; + // Object o2 = Outer.this; + Object o3 = this; + } + static class SInner { + // Object o1 = Top.this; + // Object o2 = Outer.this; + Object o3 = this; + } + interface IInner { + // Object o1 = Top.this; + // Object o2 = Outer.this; + // Object o3 = this; + } + } + + + @TB Outer f1; + @TB Outer.Inner f1a; // err + @TB Outer.SInner f2a; // err + @TB Outer.IInner f3a; // err + + Outer. @TC Inner f1b; + Outer. @TC SInner f2b; + Outer. @TC IInner f3b; + + @TB Outer. @TC Inner f1c; // err + @TB Outer. @TC SInner f2c; // err + @TB Outer. @TC IInner f3c; // err + + @TA Top. @TB Outer g1; // err + @TA Top. @TB Outer.Inner g1a; // err + @TA Top. @TB Outer.SInner g2a; // err + @TA Top. @TB Outer.IInner g3a; // err + + @TA Top. Outer. @TC Inner g1b; // err + @TA Top. Outer. @TC SInner g2b; // err + @TA Top. Outer. @TC IInner g3b; // err + + @TA Top. @TB Outer. @TC Inner g1c; // err + @TA Top. @TB Outer. @TC SInner g2c; // err + @TA Top. @TB Outer. @TC IInner g3c; // err + + @TB Outer f1r() { return null; } + + @TB Outer.Inner f1ra() { return null; } // err + @TB Outer.SInner f2ra() { return null; } // err + @TB Outer.IInner f3ra() { return null; } // err + + Outer. @TC Inner f1rb() { return null; } + Outer. @TC SInner f2rb() { return null; } + Outer. @TC IInner f3rb() { return null; } + + @TB Outer. @TC Inner f1rc() { return null; } // err + @TB Outer. @TC SInner f2rc() { return null; } // err + @TB Outer. @TC IInner f3rc() { return null; } // err + + void f1param(@TB Outer p, + @TB Outer.Inner p1, // err + Outer. @TC Inner p2, + @TB Outer. @TC Inner p3) { } // err + void f2param(@TB Outer p, + @TB Outer.SInner p1, // err + Outer. @TC SInner p2, + @TB Outer. @TC SInner p3) { } // err + void f3param(@TB Outer p, + @TB Outer.IInner p1, // err + Outer. @TC IInner p2, + @TB Outer. @TC IInner p3) { } // err + + void f1cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.Inner) o; // err + l = (Outer. @TC Inner) o; + l = (@TB Outer. @TC Inner) o; // err + } + void f2cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.SInner) o; // err + l = (Outer. @TC SInner) o; + l = (@TB Outer. @TC SInner) o; // err + } + void f3cast(Object o) { + Object l; + l = (@TB Outer) o; + l = (@TB Outer.IInner) o; // err + l = (Outer. @TC IInner) o; + l = (@TB Outer. @TC IInner) o; // err + } + + List<@TB Outer> h1; + + List<@TB Outer.Inner> h1a; // err + List<@TB Outer.SInner> h2a; // err + List<@TB Outer.IInner> h3a; // err + + List h1b; + List h2b; + List h3b; + + List<@TB Outer. @TC Inner> h1c; // err + List<@TB Outer. @TC SInner> h2c; // err + List<@TB Outer. @TC IInner> h3c; // err + + List<@TA Top. @TB Outer> k1; // err + + List<@TA Top. @TB Outer.Inner> k1a; // err + List<@TA Top. @TB Outer.SInner> k2a; // err + List<@TA Top. @TB Outer.IInner> k3a; // err + + List<@TA Top. Outer. @TC Inner> k1b; // err + List<@TA Top. Outer. @TC SInner> k2b; // err + List<@TA Top. Outer. @TC IInner> k3b; // err + + List<@TA Top. @TB Outer. @TC Inner> k1c; // err + List<@TA Top. @TB Outer. @TC SInner> k2c; // err + List<@TA Top. @TB Outer. @TC IInner> k3c; // err + + + List<@TB Outer> g1r() { return null; } + + List<@TB Outer.Inner> g1ra() { return null; } // err + List<@TB Outer.SInner> g2ra() { return null; } // err + List<@TB Outer.IInner> g3ra() { return null; } // err + + List g1rb() { return null; } + List g2rb() { return null; } + List g3rb() { return null; } + + List<@TB Outer. @TC Inner> g1rc() { return null; } // err + List<@TB Outer. @TC SInner> g2rc() { return null; } // err + List<@TB Outer. @TC IInner> g3rc() { return null; } // err + + void g1param(List<@TB Outer> p, + List<@TB Outer.Inner> p1, // err + List p2, + List<@TB Outer. @TC Inner> p3) { } // err + void g2param(List<@TB Outer> p, + List<@TB Outer.SInner> p1, // err + List p2, + List<@TB Outer. @TC SInner> p3) { } // err + void g3param(List<@TB Outer> p, + List<@TB Outer.IInner> p1, // err + List p2, + List<@TB Outer. @TC IInner> p3) { } // err + + void g1new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.Inner>(); // err + l = new @TB HashMap(); + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } + void g2new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.SInner>(); // err + l = new @TB HashMap(); + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } + void g3new(Object o) { + Object l; + l = new @TB ArrayList<@TB Outer>(); + l = new @TB ArrayList<@TB Outer.IInner>(); // err + l = new @TB HashMap(); + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } + void g4new(Object o) { + Object l; + l = new @TB ArrayList<@TA Top. @TB Outer>(); // err + l = new @TB ArrayList<@TA Top. @TB Outer.IInner>(); // err + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + l = new @TB HashMap(); // err + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.out new file mode 100644 index 00000000000..1d3cba06694 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.out @@ -0,0 +1,83 @@ +CantAnnotateStaticClass3.java:44:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:45:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:46:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:52:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:53:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:54:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:56:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:57:23: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:58:23: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:59:23: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:61:21: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:62:21: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:63:21: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:65:25: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:66:25: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:67:25: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:71:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:72:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:73:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:79:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:80:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:81:16: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:84:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:86:24: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:88:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:90:24: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:92:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:94:24: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:57:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:58:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:59:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:65:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:66:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:67:12: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:99:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:101:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:106:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:108:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:113:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:115:18: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:120:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:121:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:122:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:128:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:129:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:130:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:132:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:134:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:135:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:136:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:138:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:139:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:140:14: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:142:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:143:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:144:17: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:149:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:150:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:151:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:157:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:158:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:159:14: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:162:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:164:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:166:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:168:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:170:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:172:22: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:177:35: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:179:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:180:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:185:35: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:187:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:188:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:193:35: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:195:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:196:41: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:200:35: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:201:38: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:202:41: compiler.err.cant.type.annotate.scoping.1: @Top.TA +CantAnnotateStaticClass3.java:203:44: compiler.err.cant.type.annotate.scoping.1: @Top.TB +CantAnnotateStaticClass3.java:204:44: compiler.err.cant.type.annotate.scoping.1: @Top.TB +82 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java index c414a5f807e..9eaaffebfa7 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java @@ -5,8 +5,11 @@ * @author Mahmood Ali * @compile/fail/ref=IncompleteArray.out -XDrawDiagnostics IncompleteArray.java */ +import java.lang.annotation.*; + class IncompleteArray { int @A [] @A var; } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out index a03a09283ee..3223329beb3 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out @@ -1,2 +1,2 @@ -IncompleteArray.java:9:13: compiler.err.illegal.start.of.type +IncompleteArray.java:11:13: compiler.err.illegal.start.of.type 1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java deleted file mode 100644 index 1bb05a43aec..00000000000 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * @test /nodynamiccopyright/ - * @bug 6843077 8006775 - * @summary test incomplete vararg declaration - * @author Mahmood Ali - * @compile/fail/ref=IncompleteVararg.out -XDrawDiagnostics IncompleteVararg.java - */ -class IncompleteArray { - // the last variable may be vararg - void method(int @A test) { } -} - -@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out deleted file mode 100644 index 7cec6c9ee78..00000000000 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out +++ /dev/null @@ -1,2 +0,0 @@ -IncompleteVararg.java:10:19: compiler.err.illegal.start.of.type -1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java index 7098b93ee81..691bf93f8d1 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java @@ -5,9 +5,12 @@ * @author Mahmood Ali * @compile/fail/ref=IndexArray.out -XDrawDiagnostics IndexArray.java */ +import java.lang.annotation.*; + class IndexArray { int[] var; int a = var @A [1]; } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out index 762f38b15a8..c0ae4f88795 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out @@ -1,2 +1,2 @@ -IndexArray.java:10:15: compiler.err.illegal.start.of.expr +IndexArray.java:12:15: compiler.err.illegal.start.of.expr 1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out index cb65dba8eac..54f3bc39476 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out @@ -1,11 +1,11 @@ LintCast.java:15:21: compiler.warn.redundant.cast: java.lang.String LintCast.java:21:27: compiler.warn.redundant.cast: java.util.List -LintCast.java:27:20: compiler.warn.redundant.cast: int @A [] +LintCast.java:27:20: compiler.warn.redundant.cast: int[] LintCast.java:39:24: compiler.warn.redundant.cast: java.lang.String LintCast.java:40:26: compiler.warn.redundant.cast: java.lang.String -LintCast.java:45:23: compiler.warn.redundant.cast: java.lang.Object @A [] +LintCast.java:45:23: compiler.warn.redundant.cast: java.lang.Object[] LintCast.java:49:27: compiler.warn.redundant.cast: java.util.List -LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List<@A java.lang.String> +LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List LintCast.java:57:21: compiler.warn.redundant.cast: java.lang.Object LintCast.java:61:27: compiler.warn.redundant.cast: LintCast.Outer.Inner 10 warnings \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java index 4ed4e87aec1..e226762d5c3 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java @@ -1,35 +1,16 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* + * @test /nodynamiccopyright/ * @test * @bug 6843077 8006775 * @summary test old array syntax * @author Mahmood Ali - * @compile/fail -XDrawDiagnostics OldArray.java + * @compile/fail/ref=OldArray.out -XDrawDiagnostics OldArray.java */ +import java.lang.annotation.*; + class OldArray { String [@A] s() { return null; } } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out new file mode 100644 index 00000000000..6ae37b9ae1c --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out @@ -0,0 +1,10 @@ +OldArray.java:12:11: compiler.err.expected: ']' +OldArray.java:12:13: compiler.err.expected: token.identifier +OldArray.java:12:14: compiler.err.expected: ';' +OldArray.java:12:17: compiler.err.illegal.start.of.type +OldArray.java:12:18: compiler.err.expected: token.identifier +OldArray.java:12:19: compiler.err.expected: ';' +OldArray.java:12:22: compiler.err.illegal.start.of.type +OldArray.java:12:28: compiler.err.expected: token.identifier +OldArray.java:13:1: compiler.err.expected3: class, interface, enum +9 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java index aab3c55832c..9257786cca8 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java @@ -1,17 +1,16 @@ /* * @test /nodynamiccopyright/ * @bug 6843077 8006775 - * @summary check that A is accessible in the class type parameters + * @summary Unqualified inner type annotation not in scope. * @author Mahmood Ali * @compile/fail/ref=Scopes.out -XDrawDiagnostics Scopes.java */ -class Scopes { - // UniqueInner is not visible in the type parameters. - // One has to use Scopes.UniqueInner. - // Annotations with the default @Target are not allowed there, - // so we also get the second error about the invalid location. - // Adding the target here doesn't matter, as we don't resolve - // the annotation type. - // @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) - @interface UniqueInner { }; +import java.lang.annotation.*; + +@InnerTA +class Scopes<@InnerTA T extends @InnerTA Object> { + // The simple name TA is not in scope on header of class. + // One has to use @Scopes.TA. + @Target(ElementType.TYPE_USE) + @interface InnerTA { }; } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out index cf7eeceb9d8..e4837b0bb04 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out @@ -1,3 +1,4 @@ -Scopes.java:8:25: compiler.err.cant.resolve: kindname.class, UniqueInner, , -Scopes.java:8:24: compiler.err.annotation.type.not.applicable -2 errors +Scopes.java:10:2: compiler.err.cant.resolve: kindname.class, InnerTA, , +Scopes.java:11:34: compiler.err.cant.resolve: kindname.class, InnerTA, , +Scopes.java:11:15: compiler.err.cant.resolve: kindname.class, InnerTA, , +3 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java index f75583f9688..a76ea3a6b91 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java @@ -5,9 +5,23 @@ * @author Mahmood Ali * @compile/fail/ref=StaticFields.out -XDrawDiagnostics StaticFields.java */ +import java.lang.annotation.*; + class C { - int f; + static int f; + // static block + static { + @A C.f = 1; + } + // static ref int a = @A C.f; + // static method + static int f() { return @A C.f; } + // main + public static void main(String... args) { + int a = @A C.f; + } } +@Target(ElementType.TYPE_USE) @interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out index 3364c661fdb..bfe4f195b65 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out @@ -1,2 +1,5 @@ -StaticFields.java:10:17: compiler.err.illegal.start.of.expr -1 error +StaticFields.java:14:11: compiler.err.expected: token.identifier +StaticFields.java:17:17: compiler.err.illegal.start.of.expr +StaticFields.java:19:33: compiler.err.illegal.start.of.expr +StaticFields.java:22:19: compiler.err.illegal.start.of.expr +4 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java deleted file mode 100644 index 55fdfa3f9f2..00000000000 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * @test /nodynamiccopyright/ - * @bug 6843077 8006775 - * @summary static methods don't have receivers - * @author Mahmood Ali - * @compile/fail/ref=StaticMethods.out -XDrawDiagnostics StaticMethods.java - */ -class StaticMethods { - static void main(StaticMethods this) { } -} - -@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out deleted file mode 100644 index 2e0923a29a4..00000000000 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out +++ /dev/null @@ -1,2 +0,0 @@ -StaticMethods.java:9:34: compiler.err.non-static.cant.be.ref: kindname.variable, this -1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java index 5485e53af19..328211434c1 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java @@ -35,10 +35,12 @@ import java.lang.annotation.*; class TypeVariableCycleTest { MTV cast(CTV p) { - return (@TA MTV) p; + return (@TB MTV) p; } } -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@Target(ElementType.TYPE_USE) @interface TA {} +@Target(ElementType.TYPE_USE) +@interface TB {} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.java new file mode 100644 index 00000000000..07aeb95af4b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 1234567 + * @summary A missing annotation type in a type variable bound + * should result in the same errors with and without an + * annotation processor. + * @author Werner Dietl + * + * @compile DummyProcessor.java + * @compile/fail/ref=TypeVariableMissingTA.out -XDrawDiagnostics TypeVariableMissingTA.java + * @compile/fail/ref=TypeVariableMissingTA.out -XDrawDiagnostics -cp . -processor DummyProcessor TypeVariableMissingTA.java + */ + +import java.lang.annotation.*; + +class TypeVariableMissingTA {} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.out new file mode 100644 index 00000000000..c48faf16d87 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableMissingTA.out @@ -0,0 +1,2 @@ +TypeVariableMissingTA.java:39:40: compiler.err.cant.resolve: kindname.class, MISSING, , +1 error \ No newline at end of file diff --git a/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java b/langtools/test/tools/javac/diags/examples/CantAnnotateScoping.java similarity index 82% rename from langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java rename to langtools/test/tools/javac/diags/examples/CantAnnotateScoping.java index d3505bbd461..b7de10bc0af 100644 --- a/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java +++ b/langtools/test/tools/javac/diags/examples/CantAnnotateScoping.java @@ -21,21 +21,23 @@ * questions. */ -// key: compiler.err.cant.annotate.static.class +// key: compiler.err.cant.type.annotate.scoping import java.lang.annotation.*; -class CantAnnotateStaticClass { +class CantAnnotateScoping { @Target(ElementType.TYPE_USE) - @interface A {} + @interface TA {} + @Target(ElementType.TYPE_USE) + @interface TB {} - static class Outer { - class Inner {} + interface Outer { + interface Inner {} } // Error: - @A Outer.Inner f; + @TA @TB Outer.Inner f; // OK: - @A Outer g; + @TA @TB Outer g; } diff --git a/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java b/langtools/test/tools/javac/diags/examples/CantAnnotateScoping1.java similarity index 89% rename from langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java rename to langtools/test/tools/javac/diags/examples/CantAnnotateScoping1.java index 30d4572e601..72b1c074333 100644 --- a/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java +++ b/langtools/test/tools/javac/diags/examples/CantAnnotateScoping1.java @@ -21,21 +21,21 @@ * questions. */ -// key: compiler.err.cant.annotate.nested.type +// key: compiler.err.cant.type.annotate.scoping.1 import java.lang.annotation.*; -class CantAnnotateStaticClass { +class CantAnnotateNestedType { @Target(ElementType.TYPE_USE) - @interface A {} + @interface TA {} interface Outer { interface Inner {} } // Error: - @A Outer.Inner f; + @TA Outer.Inner f; // OK: - @A Outer g; + @TA Outer g; } diff --git a/langtools/test/tools/javac/lib/DPrinter.java b/langtools/test/tools/javac/lib/DPrinter.java index 8e67826c641..72d4fd8542e 100644 --- a/langtools/test/tools/javac/lib/DPrinter.java +++ b/langtools/test/tools/javac/lib/DPrinter.java @@ -946,8 +946,8 @@ public class DPrinter { */ public class TypeVisitor implements Type.Visitor { public Void visitAnnotatedType(AnnotatedType type, Void ignore) { - printList("typeAnnotations", type.typeAnnotations); - printType("underlyingType", type.underlyingType, Details.FULL); + printList("typeAnnotations", type.getAnnotationMirrors()); + printType("underlyingType", type.unannotatedType(), Details.FULL); return visitType(type, null); } diff --git a/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java b/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java index 0b0bd8e1364..2f1df394da1 100644 --- a/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java +++ b/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java @@ -26,6 +26,7 @@ * @bug 1234567 * @summary Annotations on types * @library /tools/javac/lib + * @ignore * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests * @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java */ From d41ff60568f9c3ed529c6ede9e2779b7e9db937d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 16 Oct 2013 10:12:22 +0200 Subject: [PATCH 102/152] 8026692: eval() throws NullPointerException with --compile-only Reviewed-by: sundar, lagergren --- .../internal/codegen/CompilationPhase.java | 2 +- .../jdk/nashorn/internal/codegen/Lower.java | 13 +++++--- nashorn/test/script/basic/JDK-8026692.js | 32 +++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026692.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java index 7a9054f6462..6c0a673d89e 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java @@ -162,7 +162,7 @@ enum CompilationPhase { LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { - return (FunctionNode)fn.accept(new Lower(compiler)); + return (FunctionNode)fn.accept(new Lower(compiler.getCodeInstaller())); } @Override diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java index d60fe0fcee1..82e9890ca16 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java @@ -68,6 +68,7 @@ import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.parser.TokenType; +import jdk.nashorn.internal.runtime.CodeInstaller; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.Source; @@ -86,13 +87,13 @@ final class Lower extends NodeOperatorVisitor { private static final DebugLogger LOG = new DebugLogger("lower"); - // needed only to get unique eval id from code installer - private final Compiler compiler; + // needed only to get unique eval id + private final CodeInstaller installer; /** * Constructor. */ - Lower(final Compiler compiler) { + Lower(final CodeInstaller installer) { super(new BlockLexicalContext() { @Override @@ -135,7 +136,7 @@ final class Lower extends NodeOperatorVisitor { return block.setIsTerminal(this, false); } }); - this.compiler = compiler; + this.installer = installer; } @Override @@ -534,6 +535,8 @@ final class Lower extends NodeOperatorVisitor { private String evalLocation(final IdentNode node) { final Source source = lc.getCurrentFunction().getSource(); final int pos = node.position(); + // Code installer is null when running with --compile-only, use 0 as id in that case + final long id = installer == null ? 0 : installer.getUniqueEvalId(); return new StringBuilder(). append(source.getName()). append('#'). @@ -541,7 +544,7 @@ final class Lower extends NodeOperatorVisitor { append(':'). append(source.getColumn(pos)). append("@"). - append(compiler.getCodeInstaller().getUniqueEvalId()). + append(id). toString(); } diff --git a/nashorn/test/script/basic/JDK-8026692.js b/nashorn/test/script/basic/JDK-8026692.js new file mode 100644 index 00000000000..f9f0f38c3da --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026692.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026692: eval() throws NullPointerException with --compile-only + * + * @test + * @option --compile-only + * @run + */ + +eval(""); From d22bf99ead40b70e1f48ecb816a33077ea5c94f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 16 Oct 2013 10:15:55 +0200 Subject: [PATCH 103/152] 8026693: getType() called on DISCARD node Reviewed-by: sundar, lagergren --- .../internal/codegen/BranchOptimizer.java | 13 ++++---- nashorn/test/script/basic/JDK-8026693.js | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8026693.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java index 5eb761e970c..bf01de0f7b8 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java @@ -84,7 +84,6 @@ final class BranchOptimizer { private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) { final Expression lhs = binaryNode.lhs(); final Expression rhs = binaryNode.rhs(); - Type widest = Type.widest(lhs.getType(), rhs.getType()); switch (binaryNode.tokenType()) { case AND: @@ -113,33 +112,33 @@ final class BranchOptimizer { case EQ: case EQ_STRICT: - codegen.loadBinaryOperands(lhs, rhs, widest); + codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); method.conditionalJump(state ? EQ : NE, true, label); return; case NE: case NE_STRICT: - codegen.loadBinaryOperands(lhs, rhs, widest); + codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); method.conditionalJump(state ? NE : EQ, true, label); return; case GE: - codegen.loadBinaryOperands(lhs, rhs, widest); + codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); method.conditionalJump(state ? GE : LT, !state, label); return; case GT: - codegen.loadBinaryOperands(lhs, rhs, widest); + codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); method.conditionalJump(state ? GT : LE, !state, label); return; case LE: - codegen.loadBinaryOperands(lhs, rhs, widest); + codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); method.conditionalJump(state ? LE : GT, state, label); return; case LT: - codegen.loadBinaryOperands(lhs, rhs, widest); + codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); method.conditionalJump(state ? LT : GE, state, label); return; diff --git a/nashorn/test/script/basic/JDK-8026693.js b/nashorn/test/script/basic/JDK-8026693.js new file mode 100644 index 00000000000..fd1dd5fa135 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8026693.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026693: getType() called on DISCARD node + * + * @test + * @run + */ + +function f() { + if(x, y) z; +} From 87c5582bacfad936ca59b5fed5030187aeacdadb Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 16 Oct 2013 11:46:06 +0200 Subject: [PATCH 104/152] 8025925: jmap fails with "field _length not found in type HeapRegionSeq" The change JDK-7163191 changed the data layout of a class that is referenced by the java code of the SA agent. This fix synchronizes the SA agent with that change. Reviewed-by: sla, mgerdin --- .../g1/G1HeapRegionTable.java | 119 ++++++++++++++++++ .../gc_implementation/g1/HeapRegionSeq.java | 47 ++----- 2 files changed, 130 insertions(+), 36 deletions(-) create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java new file mode 100644 index 00000000000..11657ce31da --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.gc_implementation.g1; + +import java.util.Iterator; +import java.util.Observable; +import java.util.Observer; + +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.runtime.VMObject; +import sun.jvm.hotspot.runtime.VMObjectFactory; +import sun.jvm.hotspot.types.AddressField; +import sun.jvm.hotspot.types.CIntegerField; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.TypeDataBase; + +// Mirror class for G1HeapRegionTable. It's essentially an index -> HeapRegion map. + +public class G1HeapRegionTable extends VMObject { + // HeapRegion** _base; + static private AddressField baseField; + // uint _length; + static private CIntegerField lengthField; + // HeapRegion** _biased_base + static private AddressField biasedBaseField; + // size_t _bias + static private CIntegerField biasField; + // uint _shift_by + static private CIntegerField shiftByField; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + static private synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("G1HeapRegionTable"); + + baseField = type.getAddressField("_base"); + lengthField = type.getCIntegerField("_length"); + biasedBaseField = type.getAddressField("_biased_base"); + biasField = type.getCIntegerField("_bias"); + shiftByField = type.getCIntegerField("_shift_by"); + } + + private HeapRegion at(long index) { + Address arrayAddr = baseField.getValue(addr); + // Offset of &_base[index] + long offset = index * VM.getVM().getAddressSize(); + Address regionAddr = arrayAddr.getAddressAt(offset); + return (HeapRegion) VMObjectFactory.newObject(HeapRegion.class, + regionAddr); + } + + public long length() { + return lengthField.getValue(addr); + } + + public long bias() { + return biasField.getValue(addr); + } + + public long shiftBy() { + return shiftByField.getValue(addr); + } + + private class HeapRegionIterator implements Iterator { + private long index; + private long length; + + @Override + public boolean hasNext() { return index < length; } + + @Override + public HeapRegion next() { return at(index++); } + + @Override + public void remove() { /* not supported */ } + + HeapRegionIterator(Address addr) { + index = 0; + length = length(); + } + } + + public Iterator heapRegionIterator() { + return new HeapRegionIterator(addr); + } + + public G1HeapRegionTable(Address addr) { + super(addr); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java index 5bd7f443de6..f8b47abeddc 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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 @@ -37,13 +37,11 @@ import sun.jvm.hotspot.types.CIntegerField; import sun.jvm.hotspot.types.Type; import sun.jvm.hotspot.types.TypeDataBase; -// Mirror class for HeapRegionSeq. It's essentially an index -> HeapRegion map. +// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable. public class HeapRegionSeq extends VMObject { - // HeapRegion** _regions; - static private AddressField regionsField; - // uint _length; - static private CIntegerField lengthField; + // G1HeapRegionTable _regions + static private long regionsFieldOffset; static { VM.registerVMInitializedObserver(new Observer() { @@ -56,44 +54,21 @@ public class HeapRegionSeq extends VMObject { static private synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("HeapRegionSeq"); - regionsField = type.getAddressField("_regions"); - lengthField = type.getCIntegerField("_length"); + regionsFieldOffset = type.getField("_regions").getOffset(); } - private HeapRegion at(long index) { - Address arrayAddr = regionsField.getValue(addr); - // Offset of &_region[index] - long offset = index * VM.getVM().getAddressSize(); - Address regionAddr = arrayAddr.getAddressAt(offset); - return (HeapRegion) VMObjectFactory.newObject(HeapRegion.class, - regionAddr); + private G1HeapRegionTable regions() { + Address regionsAddr = addr.addOffsetTo(regionsFieldOffset); + return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class, + regionsAddr); } public long length() { - return lengthField.getValue(addr); - } - - private class HeapRegionIterator implements Iterator { - private long index; - private long length; - - @Override - public boolean hasNext() { return index < length; } - - @Override - public HeapRegion next() { return at(index++); } - - @Override - public void remove() { /* not supported */ } - - HeapRegionIterator(Address addr) { - index = 0; - length = length(); - } + return regions().length(); } public Iterator heapRegionIterator() { - return new HeapRegionIterator(addr); + return regions().heapRegionIterator(); } public HeapRegionSeq(Address addr) { From 14fdc2698163ac176a952805ec1d01a3c4f3b387 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 16 Oct 2013 13:49:59 +0200 Subject: [PATCH 105/152] 6604021: RMIC is defaulting to BOOT jdk version, needs to be rmic.jar Reviewed-by: dholmes, chegar --- corba/makefiles/BuildCorba.gmk | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/corba/makefiles/BuildCorba.gmk b/corba/makefiles/BuildCorba.gmk index b177ff2d212..1e1ab5c1c7e 100644 --- a/corba/makefiles/BuildCorba.gmk +++ b/corba/makefiles/BuildCorba.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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 @@ -45,7 +45,8 @@ DISABLE_CORBA_WARNINGS:=-Xlint:all,-deprecation,-unchecked,-serial,-fallthrough, $(eval $(call SetupJavaCompiler,GENERATE_OLDBYTECODE,\ JVM:=$(JAVA),\ JAVAC:=$(NEW_JAVAC),\ - FLAGS:=$(BOOT_JDK_SOURCETARGET) -bootclasspath $(BOOT_RTJAR) $(DISABLE_CORBA_WARNINGS),\ + FLAGS := $(BOOT_JDK_SOURCETARGET) -bootclasspath $(BOOT_RTJAR)$(PATH_SEP)$(BOOT_TOOLSJAR) \ + $(DISABLE_CORBA_WARNINGS), \ SERVER_DIR:=$(SJAVAC_SERVER_DIR),\ SERVER_JVM:=$(SJAVAC_SERVER_JAVA))) @@ -181,6 +182,15 @@ ifeq ($(LOGWRAPPERS_ARE_CREATED),yes) COPY:=.prp LogStrings.properties,\ BIN:=$(CORBA_OUTPUTDIR)/classes)) + $(eval $(call SetupJavaCompilation,BUILD_BOOTSTRAP_CORBA, \ + SETUP := GENERATE_OLDBYTECODE, \ + SRC := $(BUILD_CORBA_SRC), \ + EXCLUDES := $(BUILD_CORBA_EXCLUDES), \ + EXCLUDE_FILES := $(BUILD_CORBA_EXCLUDE_FILES), \ + COPY := $(BUILD_CORBA_COPY), \ + BIN := $(CORBA_OUTPUTDIR)/btclasses/corba_classes, \ + JAR := $(CORBA_OUTPUTDIR)/btjars/btcorba.jar)) + # Separate src.zip call to include sources that were excluded in the build to # mimic behavior in old build system. $(eval $(call SetupZipArchive,ARCHIVE_BUILD_CORBA,\ @@ -239,6 +249,7 @@ ifeq ($(LOGWRAPPERS_ARE_CREATED),yes) all: $(CORBA_OUTPUTDIR)/btjars/stripproperties.jar \ $(CORBA_OUTPUTDIR)/btjars/idlj.jar \ $(CORBA_OUTPUTDIR)/btjars/logutil.jar \ + $(CORBA_OUTPUTDIR)/btjars/btcorba.jar \ $(CORBA_OUTPUTDIR)/dist/lib/classes.jar \ $(CORBA_OUTPUTDIR)/dist/lib/src.zip \ $(CORBA_OUTPUTDIR)/dist/lib/bin.zip From f1ff8b5c67c9783ee440c35d4572b948b2d15fe4 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 16 Oct 2013 13:50:05 +0200 Subject: [PATCH 106/152] 6604021: RMIC is defaulting to BOOT jdk version, needs to be rmic.jar Reviewed-by: dholmes, chegar --- common/makefiles/JavaCompilation.gmk | 10 +++++----- common/makefiles/RMICompilation.gmk | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/common/makefiles/JavaCompilation.gmk b/common/makefiles/JavaCompilation.gmk index ecc59e3532f..11b0b46bfb9 100644 --- a/common/makefiles/JavaCompilation.gmk +++ b/common/makefiles/JavaCompilation.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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 @@ -371,8 +371,8 @@ define SetupJavaCompilation # INCLUDE_FILES:="com/sun/SolarisFoobar.java" means only compile this file! # EXCLUDE_FILES:="com/sun/SolarisFoobar.java" means do not compile this particular file! # "SolarisFoobar.java" means do not compile SolarisFoobar, wherever it is found. - # JAVAC_SOURCE_PATH_UGLY_OVERRIDE:=Don't use this. This forces an explicit -sourcepath to javac. - # Its only here until we cleanup some nasty source code pasta in the jdk. + # JAVAC_SOURCE_PATH_OVERRIDE:=This forces an explicit -sourcepath to javac instead of the complete + # source roots from SRC. This is sometimes needed when compiling specific subsets of the source. # HEADERS:=path to directory where all generated c-headers are written. # DEPENDS:=Extra dependecy $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) @@ -474,8 +474,8 @@ define SetupJavaCompilation endif # Prep the source paths. - ifneq ($$($1_JAVAC_SOURCE_PATH_UGLY_OVERRIDE),) - $$(eval $$(call replace_space_with_pathsep,$1_SRCROOTSC,$$($1_JAVAC_SOURCE_PATH_UGLY_OVERRIDE))) + ifneq ($$($1_JAVAC_SOURCE_PATH_OVERRIDE),) + $$(eval $$(call replace_space_with_pathsep,$1_SRCROOTSC,$$($1_JAVAC_SOURCE_PATH_OVERRIDE))) else $$(eval $$(call replace_space_with_pathsep,$1_SRCROOTSC,$$($1_SRC))) endif diff --git a/common/makefiles/RMICompilation.gmk b/common/makefiles/RMICompilation.gmk index acbc7054ceb..0b8f974f669 100644 --- a/common/makefiles/RMICompilation.gmk +++ b/common/makefiles/RMICompilation.gmk @@ -38,7 +38,7 @@ define SetupRMICompilation $(call LogSetupMacroEntry,SetupRMICompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupRMICompilation, please update RMICompilation.gmk)) - $1_DEP_FILE := $$($1_STUB_CLASSES_DIR)/$1_rmic + $1_DEP_FILE := $$($1_STUB_CLASSES_DIR)/_the.$1_rmic.generated $1_CLASSES_SLASH := $$(subst .,/,$$($1_CLASSES)) $1_CLASS_FILES := $$(addprefix $$($1_CLASSES_DIR)/,$$(addsuffix .class,$$($1_CLASSES_SLASH))) @@ -88,10 +88,9 @@ define SetupRMICompilation $(RMIC) $$($1_ARGS2) -classpath "$$($1_CLASSES_DIR)" \ -d $$($1_STUB_CLASSES_DIR) $$($1_DOLLAR_SAFE_CLASSES);\ fi; + $(TOUCH) $$@ - $1 := $$($1_TARGETS) + $1 := $$($1_TARGETS) $$($1_DEP_FILE) - # By marking as secondary, this "touch" file doesn't need to be touched and will never exist. - .SECONDARY: $$($1_DEP_FILE) endef From ef68cc1fc1b29413f682daf200ea3e62b4bcebb6 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 16 Oct 2013 10:47:21 -0700 Subject: [PATCH 107/152] 8026704: Build failure with --enable-debug Reviewed-by: ksrini --- .../com/sun/tools/javac/code/Flags.java | 8 +- .../com/sun/tools/javac/comp/Flow.java | 4 +- .../sun/tools/javac/comp/LambdaToMethod.java | 12 +- .../classes/com/sun/tools/javac/jvm/Gen.java | 4 +- .../javac/lambda/LocalVariableTable.java | 206 ------------------ 5 files changed, 6 insertions(+), 228 deletions(-) delete mode 100644 langtools/test/tools/javac/lambda/LocalVariableTable.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 3b1c40e2c92..2f59cfab7fd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -270,11 +270,6 @@ public class Flags { */ public static final long POTENTIALLY_AMBIGUOUS = 1L<<48; - /** - * Flag that marks a synthetic method body for a lambda expression - */ - public static final long LAMBDA_METHOD = 1L<<49; - /** Modifier masks. */ public static final int @@ -383,8 +378,7 @@ public class Flags { NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), BAD_OVERRIDE(Flags.BAD_OVERRIDE), SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), - THROWS(Flags.THROWS), - LAMBDA_METHOD(Flags.LAMBDA_METHOD); + THROWS(Flags.THROWS); Flag(long flag) { this.value = flag; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 8237d77a22b..8c69c814965 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1718,9 +1718,9 @@ public class Flow { if (tree.body == null) { return; } - /* Ignore synthetic methods, except for translated lambda methods. + /* MemberEnter can generate synthetic methods, ignore them */ - if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) { + if ((tree.sym.flags() & SYNTHETIC) != 0) { return; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 3329b78ff1b..e56aa535706 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -30,7 +30,6 @@ import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; import com.sun.tools.javac.code.Attribute; -import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol; @@ -1756,7 +1755,7 @@ public class LambdaToMethod extends TreeTranslator { ((VarSymbol)ret).pos = ((VarSymbol)sym).pos; break; case CAPTURED_VAR: - ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym) { + ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { //keep mapping with original captured symbol @@ -1764,13 +1763,6 @@ public class LambdaToMethod extends TreeTranslator { } }; break; - case LOCAL_VAR: - ret = new VarSymbol(FINAL, name, types.erasure(sym.type), translatedSym); - break; - case PARAM: - ret = new VarSymbol(FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym); - ((VarSymbol) ret).adr = ((VarSymbol) sym).adr; - break; default: ret = makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym); } @@ -1853,7 +1845,7 @@ public class LambdaToMethod extends TreeTranslator { // If instance access isn't needed, make it static. // Interface instance methods must be default methods. // Lambda methods are private synthetic. - translatedSym.flags_field = SYNTHETIC | LAMBDA_METHOD | + translatedSym.flags_field = SYNTHETIC | PRIVATE | (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index 34e61a011ee..b48b727090f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -2892,8 +2892,7 @@ public class Gen extends JCTree.Visitor { @Override public void visitMethodDef(JCMethodDecl tree) { - if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0 - && (tree.sym.flags() & LAMBDA_METHOD) == 0) { + if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0) { return; } if (tree.name.equals(names.clinit)) { @@ -2907,7 +2906,6 @@ public class Gen extends JCTree.Visitor { return; } currentMethod = tree.sym; - super.visitMethodDef(tree); } diff --git a/langtools/test/tools/javac/lambda/LocalVariableTable.java b/langtools/test/tools/javac/lambda/LocalVariableTable.java deleted file mode 100644 index a829d702eb8..00000000000 --- a/langtools/test/tools/javac/lambda/LocalVariableTable.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8025998 - * @summary Missing LV table in lambda bodies - * @compile -g LocalVariableTable.java - * @run main LocalVariableTable - */ - -import java.lang.annotation.*; -import java.util.*; -import com.sun.tools.classfile.*; - -/* - * The test checks that a LocalVariableTable attribute is generated for the - * method bodies representing lambda expressions, and checks that the expected - * set of entries is found in the attribute. - * - * Since the bug was about missing entries in the LVT, not malformed entries, - * the test is not intended to be a detailed test of the contents of each - * LocalVariableTable entry: it is assumed that if a entry is present, it - * will have the correct contents. - * - * The test looks for test cases represented by nested classes whose - * name begins with "Lambda". Each such class contains a lambda expression - * that will mapped into a lambda method, and because the test is compiled - * with -g, these methods should have a LocalVariableTable. The set of - * expected names in the LVT is provided in an annotation on the class for - * the test case. - */ -public class LocalVariableTable { - public static void main(String... args) throws Exception { - new LocalVariableTable().run(); - } - - void run() throws Exception { - // the declared classes are returned in an unspecified order, - // so for neatness, sort them by name before processing them - Class[] classes = getClass().getDeclaredClasses(); - Arrays.sort(classes, (c1, c2) -> c1.getName().compareTo(c2.getName())); - - for (Class c : classes) { - if (c.getSimpleName().startsWith("Lambda")) - check(c); - } - if (errors > 0) - throw new Exception(errors + " errors found"); - } - - /** Check an individual test case. */ - void check(Class c) throws Exception { - System.err.println("Checking " + c.getSimpleName()); - - Expect expect = c.getAnnotation(Expect.class); - if (expect == null) { - error("@Expect not found for class " + c.getSimpleName()); - return; - } - - ClassFile cf = ClassFile.read(getClass().getResource(c.getName() + ".class").openStream()); - Method m = getLambdaMethod(cf); - if (m == null) { - error("lambda method not found"); - return; - } - - Code_attribute code = (Code_attribute) m.attributes.get(Attribute.Code); - if (code == null) { - error("Code attribute not found"); - return; - } - - LocalVariableTable_attribute lvt = - (LocalVariableTable_attribute) code.attributes.get(Attribute.LocalVariableTable); - if (lvt == null) { - error("LocalVariableTable attribute not found"); - return; - } - - Set foundNames = new LinkedHashSet<>(); - for (LocalVariableTable_attribute.Entry e: lvt.local_variable_table) { - foundNames.add(cf.constant_pool.getUTF8Value(e.name_index)); - } - - Set expectNames = new LinkedHashSet<>(Arrays.asList(expect.value())); - if (!foundNames.equals(expectNames)) { - Set foundOnly = new LinkedHashSet<>(foundNames); - foundOnly.removeAll(expectNames); - for (String s: foundOnly) - error("Unexpected name found: " + s); - Set expectOnly = new LinkedHashSet<>(expectNames); - expectOnly.removeAll(foundNames); - for (String s: expectOnly) - error("Expected name not found: " + s); - } - } - - /** Get a method whose name begins "lambda$...". */ - Method getLambdaMethod(ClassFile cf) throws ConstantPoolException { - for (Method m: cf.methods) { - if (m.getName(cf.constant_pool).startsWith("lambda$")) - return m; - } - return null; - } - - /** Report an error. */ - void error(String msg) { - System.err.println("Error: " + msg); - errors++; - } - - int errors; - - /** - * Annotation used to provide the set of names expected in the LVT attribute. - */ - @Retention(RetentionPolicy.RUNTIME) - @interface Expect { - String[] value(); - } - - /** Functional interface with nullary method. */ - interface Run0 { - public void run(); - } - - /** Functional interface with 1-ary method. */ - interface Run1 { - public void run(int a0); - } - - /** Functional interface with 2-ary method. */ - interface Run2 { - public void run(int a0, int a1); - } - - /* - * ---------- Test cases --------------------------------------------------- - */ - - @Expect({ "x" }) - static class Lambda_Args0_Local1 { - Run0 r = () -> { int x = 0; }; - } - - @Expect({ "x", "this" }) - static class Lambda_Args0_Local1_this { - int v; - Run0 r = () -> { int x = v; }; - } - - @Expect({ "a" }) - static class Lambda_Args1_Local0 { - Run1 r = (a) -> { }; - } - - @Expect({ "a", "x" }) - static class Lambda_Args1_Local1 { - Run1 r = (a) -> { int x = a; }; - } - - @Expect({ "a", "x" }) - static class Lambda_Args1_Local1_Captured1 { - void m() { - int v = 0; - Run1 r = (a) -> { int x = a + v; }; - } - } - - @Expect({ "a1", "a2", "x1", "x2", "this" }) - static class Lambda_Args2_Local2_Captured2_this { - int v; - void m() { - int v1 = 0; - int v2 = 0; - Run2 r = (a1, a2) -> { - int x1 = a1 + v1 + v; - int x2 = a2 + v2 + v; - }; - } - } -} - From 64b6d2b5e52a3e4d7e43418e08eb98e291ad5e4e Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Wed, 16 Oct 2013 11:13:15 -0700 Subject: [PATCH 108/152] 8009303: Tiered: incorrect results in VM tests stringconcat with -Xcomp -XX:+DeoptimizeALot on solaris-amd64 Do memory flow analysis in string concat optimizier to exclude cases when computation of arguments to StringBuffer::append has side effects Reviewed-by: kvn, twisti --- .../src/share/vm/opto/idealGraphPrinter.cpp | 6 +- hotspot/src/share/vm/opto/stringopts.cpp | 158 +++++++++++++++++- 2 files changed, 157 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 9f67a652eec..4589f6e4a8d 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -616,7 +616,11 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) { buffer[0] = 0; _chaitin->dump_register(node, buffer); print_prop("reg", buffer); - print_prop("lrg", _chaitin->_lrg_map.live_range_id(node)); + uint lrg_id = 0; + if (node->_idx < _chaitin->_lrg_map.size()) { + lrg_id = _chaitin->_lrg_map.live_range_id(node); + } + print_prop("lrg", lrg_id); } node->_in_dump_cnt--; diff --git a/hotspot/src/share/vm/opto/stringopts.cpp b/hotspot/src/share/vm/opto/stringopts.cpp index 71abc31bae9..0306bc24a23 100644 --- a/hotspot/src/share/vm/opto/stringopts.cpp +++ b/hotspot/src/share/vm/opto/stringopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. 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 @@ -50,10 +50,11 @@ class StringConcat : public ResourceObj { Node* _arguments; // The list of arguments to be concatenated GrowableArray _mode; // into a String along with a mode flag // indicating how to treat the value. - + Node_List _constructors; // List of constructors (many in case of stacked concat) Node_List _control; // List of control nodes that will be deleted Node_List _uncommon_traps; // Uncommon traps that needs to be rewritten // to restart at the initial JVMState. + public: // Mode for converting arguments to Strings enum { @@ -73,6 +74,7 @@ class StringConcat : public ResourceObj { _arguments->del_req(0); } + bool validate_mem_flow(); bool validate_control_flow(); void merge_add() { @@ -189,6 +191,10 @@ class StringConcat : public ResourceObj { assert(!_control.contains(ctrl), "only push once"); _control.push(ctrl); } + void add_constructor(Node* init) { + assert(!_constructors.contains(init), "only push once"); + _constructors.push(init); + } CallStaticJavaNode* end() { return _end; } AllocateNode* begin() { return _begin; } Node* string_alloc() { return _string_alloc; } @@ -301,6 +307,12 @@ StringConcat* StringConcat::merge(StringConcat* other, Node* arg) { } } result->set_allocation(other->_begin); + for (uint i = 0; i < _constructors.size(); i++) { + result->add_constructor(_constructors.at(i)); + } + for (uint i = 0; i < other->_constructors.size(); i++) { + result->add_constructor(other->_constructors.at(i)); + } result->_multiple = true; return result; } @@ -510,7 +522,8 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) { sc->add_control(constructor); sc->add_control(alloc); sc->set_allocation(alloc); - if (sc->validate_control_flow()) { + sc->add_constructor(constructor); + if (sc->validate_control_flow() && sc->validate_mem_flow()) { return sc; } else { return NULL; @@ -620,7 +633,7 @@ PhaseStringOpts::PhaseStringOpts(PhaseGVN* gvn, Unique_Node_List*): #endif StringConcat* merged = sc->merge(other, arg); - if (merged->validate_control_flow()) { + if (merged->validate_control_flow() && merged->validate_mem_flow()) { #ifndef PRODUCT if (PrintOptimizeStringConcat) { tty->print_cr("stacking would succeed"); @@ -708,6 +721,139 @@ void PhaseStringOpts::remove_dead_nodes() { } +bool StringConcat::validate_mem_flow() { + Compile* C = _stringopts->C; + + for (uint i = 0; i < _control.size(); i++) { +#ifndef PRODUCT + Node_List path; +#endif + Node* curr = _control.at(i); + if (curr->is_Call() && curr != _begin) { // For all calls except the first allocation + // Now here's the main invariant in our case: + // For memory between the constructor, and appends, and toString we should only see bottom memory, + // produced by the previous call we know about. + if (!_constructors.contains(curr)) { + NOT_PRODUCT(path.push(curr);) + Node* mem = curr->in(TypeFunc::Memory); + assert(mem != NULL, "calls should have memory edge"); + assert(!mem->is_Phi(), "should be handled by control flow validation"); + NOT_PRODUCT(path.push(mem);) + while (mem->is_MergeMem()) { + for (uint i = 1; i < mem->req(); i++) { + if (i != Compile::AliasIdxBot && mem->in(i) != C->top()) { +#ifndef PRODUCT + if (PrintOptimizeStringConcat) { + tty->print("fusion has incorrect memory flow (side effects) for "); + _begin->jvms()->dump_spec(tty); tty->cr(); + path.dump(); + } +#endif + return false; + } + } + // skip through a potential MergeMem chain, linked through Bot + mem = mem->in(Compile::AliasIdxBot); + NOT_PRODUCT(path.push(mem);) + } + // now let it fall through, and see if we have a projection + if (mem->is_Proj()) { + // Should point to a previous known call + Node *prev = mem->in(0); + NOT_PRODUCT(path.push(prev);) + if (!prev->is_Call() || !_control.contains(prev)) { +#ifndef PRODUCT + if (PrintOptimizeStringConcat) { + tty->print("fusion has incorrect memory flow (unknown call) for "); + _begin->jvms()->dump_spec(tty); tty->cr(); + path.dump(); + } +#endif + return false; + } + } else { + assert(mem->is_Store() || mem->is_LoadStore(), err_msg_res("unexpected node type: %s", mem->Name())); +#ifndef PRODUCT + if (PrintOptimizeStringConcat) { + tty->print("fusion has incorrect memory flow (unexpected source) for "); + _begin->jvms()->dump_spec(tty); tty->cr(); + path.dump(); + } +#endif + return false; + } + } else { + // For memory that feeds into constructors it's more complicated. + // However the advantage is that any side effect that happens between the Allocate/Initialize and + // the constructor will have to be control-dependent on Initialize. + // So we actually don't have to do anything, since it's going to be caught by the control flow + // analysis. +#ifdef ASSERT + // Do a quick verification of the control pattern between the constructor and the initialize node + assert(curr->is_Call(), "constructor should be a call"); + // Go up the control starting from the constructor call + Node* ctrl = curr->in(0); + IfNode* iff = NULL; + RegionNode* copy = NULL; + + while (true) { + // skip known check patterns + if (ctrl->is_Region()) { + if (ctrl->as_Region()->is_copy()) { + copy = ctrl->as_Region(); + ctrl = copy->is_copy(); + } else { // a cast + assert(ctrl->req() == 3 && + ctrl->in(1) != NULL && ctrl->in(1)->is_Proj() && + ctrl->in(2) != NULL && ctrl->in(2)->is_Proj() && + ctrl->in(1)->in(0) == ctrl->in(2)->in(0) && + ctrl->in(1)->in(0) != NULL && ctrl->in(1)->in(0)->is_If(), + "must be a simple diamond"); + Node* true_proj = ctrl->in(1)->is_IfTrue() ? ctrl->in(1) : ctrl->in(2); + for (SimpleDUIterator i(true_proj); i.has_next(); i.next()) { + Node* use = i.get(); + assert(use == ctrl || use->is_ConstraintCast(), + err_msg_res("unexpected user: %s", use->Name())); + } + + iff = ctrl->in(1)->in(0)->as_If(); + ctrl = iff->in(0); + } + } else if (ctrl->is_IfTrue()) { // null checks, class checks + iff = ctrl->in(0)->as_If(); + assert(iff->is_If(), "must be if"); + // Verify that the other arm is an uncommon trap + Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con); + CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava(); + assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommond trap"); + ctrl = iff->in(0); + } else { + break; + } + } + + assert(ctrl->is_Proj(), "must be a projection"); + assert(ctrl->in(0)->is_Initialize(), "should be initialize"); + for (SimpleDUIterator i(ctrl); i.has_next(); i.next()) { + Node* use = i.get(); + assert(use == copy || use == iff || use == curr || use->is_CheckCastPP() || use->is_Load(), + err_msg_res("unexpected user: %s", use->Name())); + } +#endif // ASSERT + } + } + } + +#ifndef PRODUCT + if (PrintOptimizeStringConcat) { + tty->print("fusion has correct memory flow for "); + _begin->jvms()->dump_spec(tty); tty->cr(); + tty->cr(); + } +#endif + return true; +} + bool StringConcat::validate_control_flow() { // We found all the calls and arguments now lets see if it's // safe to transform the graph as we would expect. @@ -753,7 +899,7 @@ bool StringConcat::validate_control_flow() { } } - // Skip backwards through the control checking for unexpected contro flow + // Skip backwards through the control checking for unexpected control flow Node* ptr = _end; bool fail = false; while (ptr != _begin) { @@ -936,7 +1082,7 @@ bool StringConcat::validate_control_flow() { if (PrintOptimizeStringConcat && !fail) { ttyLocker ttyl; tty->cr(); - tty->print("fusion would succeed (%d %d) for ", null_check_count, _uncommon_traps.size()); + tty->print("fusion has correct control flow (%d %d) for ", null_check_count, _uncommon_traps.size()); _begin->jvms()->dump_spec(tty); tty->cr(); for (int i = 0; i < num_arguments(); i++) { argument(i)->dump(); From a360c92c70d4c930d73bed994994ee7a098c70e8 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 16 Oct 2013 20:24:46 +0200 Subject: [PATCH 109/152] 8025715: Split CompileNativeLibraries.gmk Reviewed-by: erikj --- jdk/makefiles/CompileNativeLibraries.gmk | 3381 +---------------- jdk/makefiles/lib/Awt2dLibraries.gmk | 1529 ++++++++ jdk/makefiles/lib/CoreLibraries.gmk | 510 +++ jdk/makefiles/lib/NetworkingLibraries.gmk | 98 + jdk/makefiles/lib/NioLibraries.gmk | 185 + jdk/makefiles/lib/PlatformLibraries.gmk | 286 ++ jdk/makefiles/lib/SecurityLibraries.gmk | 289 ++ jdk/makefiles/lib/ServiceabilityLibraries.gmk | 431 +++ jdk/makefiles/lib/SoundLibraries.gmk | 237 ++ 9 files changed, 3573 insertions(+), 3373 deletions(-) create mode 100644 jdk/makefiles/lib/Awt2dLibraries.gmk create mode 100644 jdk/makefiles/lib/CoreLibraries.gmk create mode 100644 jdk/makefiles/lib/NetworkingLibraries.gmk create mode 100644 jdk/makefiles/lib/NioLibraries.gmk create mode 100644 jdk/makefiles/lib/PlatformLibraries.gmk create mode 100644 jdk/makefiles/lib/SecurityLibraries.gmk create mode 100644 jdk/makefiles/lib/ServiceabilityLibraries.gmk create mode 100644 jdk/makefiles/lib/SoundLibraries.gmk diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 294f73b1b21..57ef12e32cb 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -56,9 +56,7 @@ BUILD_LIBRARIES = # Absolute paths to lib files on windows for use in LDFLAGS. Should figure out a more # elegant solution to this. -WIN_VERIFY_LIB := $(JDK_OUTPUTDIR)/objs/libverify/verify.lib WIN_JAVA_LIB := $(JDK_OUTPUTDIR)/objs/libjava/java.lib -WIN_AWT_LIB := $(JDK_OUTPUTDIR)/objs/libawt/awt.lib # Use this variable to set DEBUG_SYMBOLS true on windows for all libraries, but # not on other platforms. @@ -71,3386 +69,23 @@ ifdef OPENJDK DEBUG_ALL_BINARIES := true endif -# -# TODO replace with X_FLAGS / X_LIBS -# and add them to configure -# -OPENWIN_LIB := $(OPENWIN_HOME)/lib - ########################################################################################## -BUILD_LIBFDLIBM_OPTIMIZATION := HIGH +include lib/CoreLibraries.gmk -ifneq ($(OPENJDK_TARGET_OS), solaris) - BUILD_LIBFDLIBM_OPTIMIZATION := NONE -endif +include lib/PlatformLibraries.gmk -ifneq ($(OPENJDK_TARGET_OS), macosx) - $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM, \ - STATIC_LIBRARY := fdlibm, \ - OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ - SRC := $(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/src, \ - LANG := C, \ - OPTIMIZATION := $(BUILD_LIBFDLIBM_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include, \ - CFLAGS_windows_debug := -DLOGGING, \ - ARFLAGS := $(ARFLAGS), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) +include lib/NetworkingLibraries.gmk -else +include lib/NioLibraries.gmk -# On macosx the old build does partial (incremental) linking of fdlibm instead of -# a plain static library. - $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM_MAC, \ - LIBRARY := fdlibm, \ - OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ - SRC := $(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/src, \ - LANG := C, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include, \ - LDFLAGS := -nostdlib -r -arch x86_64, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) +include lib/SecurityLibraries.gmk - BUILD_LIBFDLIBM := $(JDK_OUTPUTDIR)/objs/$(LIBRARY_PREFIX)fdlibm$(STATIC_LIBRARY_SUFFIX) - $(BUILD_LIBFDLIBM): $(BUILD_LIBFDLIBM_MAC) - $(call install-file) +include lib/ServiceabilityLibraries.gmk -endif -BUILD_LIBRARIES += $(BUILD_LIBFDLIBM) - -########################################################################################## - -BUILD_LIBVERIFY_SRC := check_code.c check_format.c - -ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU) - endif -endif - -LIBVERIFY_OPTIMIZATION := HIGH -ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) - ifeq ($(ENABLE_DEBUG_SYMBOLS), true) - LIBVERIFY_OPTIMIZATION := LOW - endif -endif - - -$(eval $(call SetupNativeCompilation,BUILD_LIBVERIFY, \ - LIBRARY := verify, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/common, \ - INCLUDE_FILES := $(BUILD_LIBVERIFY_SRC), \ - LANG := C, \ - OPTIMIZATION := $(LIBVERIFY_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libverify/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_posix := -ljvm -lc, \ - LDFLAGS_SUFFIX_windows := jvm.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=verify.dll" \ - -D "JDK_INTERNAL_NAME=verify" \ - -D "JDK_FTYPE=0x2L", \ - REORDER := $(BUILD_LIBVERIFY_REORDER), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libverify, \ - DEBUG_SYMBOLS := true)) - -BUILD_LIBRARIES += $(BUILD_LIBVERIFY) - -########################################################################################## - -LIBJAVA_SRC_DIRS := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/lang \ - $(JDK_TOPDIR)/src/share/native/java/lang \ - $(JDK_TOPDIR)/src/share/native/java/lang/ref \ - $(JDK_TOPDIR)/src/share/native/java/lang/reflect \ - $(JDK_TOPDIR)/src/share/native/java/io \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io \ - $(JDK_TOPDIR)/src/share/native/java/nio \ - $(JDK_TOPDIR)/src/share/native/java/security \ - $(JDK_TOPDIR)/src/share/native/common \ - $(JDK_TOPDIR)/src/share/native/sun/misc \ - $(JDK_TOPDIR)/src/share/native/sun/reflect \ - $(JDK_TOPDIR)/src/share/native/java/util \ - $(JDK_TOPDIR)/src/share/native/java/util/concurrent/atomic \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/common \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/util - -ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/util/locale/provider -else - LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/util/locale/provider -endif - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/provider \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/io -endif - -LIBJAVA_CFLAGS := $(foreach dir, $(LIBJAVA_SRC_DIRS), -I$(dir)) \ - -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include \ - -DARCHPROPNAME='"$(OPENJDK_TARGET_CPU_OSARCH)"' - -LIBJAVA_CFLAGS += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ - -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \ - -DJDK_MICRO_VERSION='"$(JDK_MICRO_VERSION)"' \ - -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' - -ifneq (, $(JDK_UPDATE_VERSION)) - LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"' -endif - -LIBJAVA_EXCLUDE_FILES := check_code.c check_format.c jspawnhelper.c - -ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBJAVA_EXCLUDE_FILES += java_props_macosx.c -else - BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c - BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c -endif - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBJAVA_EXCLUDE_FILES += \ - UNIXProcess_md.c \ - UnixFileSystem_md.c \ - FileSystemPreferences.c -else - LIBJAVA_EXCLUDE_FILES += \ - ProcessImpl_md.c \ - WinNTFileSystem_md.c \ - dirent_md.c \ - WindowsPreferences.c \ - sun/security/provider/WinCAPISeedGenerator.c \ - sun/io/Win32ErrorMode.c -endif - -ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - LIBJAVA_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libjava/reorder-$(OPENJDK_TARGET_CPU) - endif -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \ - LIBRARY := java, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJAVA_SRC_DIRS), \ - EXCLUDES := fdlibm/src zip, \ - EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \ - LANG := C, \ - OPTIMIZATION := HIGH, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBJAVA_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjava/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_posix := -ljvm -lverify, \ - LDFLAGS_SUFFIX_solaris := -lsocket -lnsl -lscf $(LIBDL) $(BUILD_LIBFDLIBM) -lc, \ - LDFLAGS_SUFFIX_linux := $(LIBDL) $(BUILD_LIBFDLIBM), \ - LDFLAGS_SUFFIX_macosx := -L$(JDK_OUTPUTDIR)/objs/ -lfdlibm \ - -framework CoreFoundation \ - -framework Foundation \ - -framework Security -framework SystemConfiguration, \ - LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \ - jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ - shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \ - advapi32.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=java.dll" \ - -D "JDK_INTERNAL_NAME=java" \ - -D "JDK_FTYPE=0x2L", \ - REORDER := $(LIBJAVA_REORDER), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjava, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -BUILD_LIBRARIES += $(BUILD_LIBJAVA) - -$(BUILD_LIBJAVA): $(LIBJLI_BINARY) - -$(BUILD_LIBJAVA): $(BUILD_LIBVERIFY) - -$(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM) - -########################################################################################## - -BUILD_LIBMLIB_SRC := $(JDK_TOPDIR)/src/share/native/sun/awt/medialib -BUILD_LIBMLIB_CFLAGS := -D__USE_J2D_NAMES -D__MEDIALIB_OLD_NAMES \ - -I$(BUILD_LIBMLIB_SRC) \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib - -BUILD_LIBMLIB_LDLIBS := -BUILD_LIBMLIB_IMAGE_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libmlib_image/mapfile-vers - -BUILD_LIBMLIB_CFLAGS += -DMLIB_NO_LIBSUNMATH - -ifeq ($(OPENJDK_TARGET_CPU_BITS), 64) - BUILD_LIBMLIB_CFLAGS += -DMLIB_OS64BIT -endif - -ifneq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBMLIB_LDLIBS += $(LIBM) $(LIBDL) -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE, \ - LIBRARY := mlib_image, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBMLIB_SRC), \ - EXCLUDE_FILES := awt_ImagingLib.c mlib_c_ImageBlendTable.c, \ - LANG := C, \ - OPTIMIZATION := HIGHEST, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(BUILD_LIBMLIB_CFLAGS), \ - MAPFILE := $(BUILD_LIBMLIB_IMAGE_MAPFILE), \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(BUILD_LIBMLIB_LDLIBS) \ - $(LDFLAGS_JDKLIB_SUFFIX), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=mlib_image.dll" \ - -D "JDK_INTERNAL_NAME=mlib_image" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libmlib_image, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBMLIB_IMAGE): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBMLIB_IMAGE) - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) - - BUILD_LIBMLIB_IMAGE_V_FILES := \ - mlib_v_ImageLookUp.c \ - mlib_ImageCreate.c \ - mlib_ImageAffine.c \ - mlib_ImageConvMxN.c \ - mlib_ImageConvKernelConvert.c \ - mlib_sys.c \ - mlib_ImageLookUp_64.c \ - mlib_ImageLookUp_Bit.c \ - mlib_ImageColorTrue2Index.c \ - mlib_c_ImageThresh1_U8.c \ - mlib_v_ImageLookUpS16S16Func.c \ - mlib_v_ImageLookUpS16S32Func.c \ - mlib_v_ImageLookUpS16U16Func.c \ - mlib_v_ImageLookUpS16U8Func.c \ - mlib_v_ImageLookUpS32S16Func.c \ - mlib_v_ImageLookUpS32S32Func.c \ - mlib_v_ImageLookUpS32U16Func.c \ - mlib_v_ImageLookUpS32U8Func.c \ - mlib_v_ImageLookUpSIS16S16Func.c \ - mlib_v_ImageLookUpSIS16S32Func.c \ - mlib_v_ImageLookUpSIS16U16Func.c \ - mlib_v_ImageLookUpSIS16U8Func.c \ - mlib_v_ImageLookUpSIS32S16Func.c \ - mlib_v_ImageLookUpSIS32S32Func.c \ - mlib_v_ImageLookUpSIS32U16Func.c \ - mlib_v_ImageLookUpSIS32U8Func.c \ - mlib_v_ImageLookUpSIU16S16Func.c \ - mlib_v_ImageLookUpSIU16S32Func.c \ - mlib_v_ImageLookUpSIU16U16Func.c \ - mlib_v_ImageLookUpSIU16U8Func.c \ - mlib_v_ImageLookUpSIU8S16Func.c \ - mlib_v_ImageLookUpSIU8S32Func.c \ - mlib_v_ImageLookUpSIU8U16Func.c \ - mlib_v_ImageLookUpSIU8U8Func.c \ - mlib_v_ImageLookUpU16S16Func.c \ - mlib_v_ImageLookUpU16S32Func.c \ - mlib_v_ImageLookUpU16U16Func.c \ - mlib_v_ImageLookUpU16U8Func.c \ - mlib_v_ImageLookUpU8S16Func.c \ - mlib_v_ImageLookUpU8S32Func.c \ - mlib_v_ImageLookUpU8U16Func.c \ - mlib_v_ImageLookUpU8U8Func.c \ - mlib_v_ImageAffineIndex_BC.c \ - mlib_v_ImageAffine_BC.c \ - mlib_v_ImageAffine_BC_S16.c \ - mlib_v_ImageAffine_BC_U16.c \ - mlib_v_ImageAffine_BL.c \ - mlib_v_ImageAffine_BL_S16.c \ - mlib_v_ImageAffine_BL_U16.c \ - mlib_v_ImageAffine_NN.c \ - mlib_v_ImageFilters.c \ - mlib_ImageAffineEdge.c \ - mlib_ImageAffine_BC_D64.c \ - mlib_ImageAffine_BC_F32.c \ - mlib_ImageAffine_BC_S32.c \ - mlib_ImageAffine_BL_D64.c \ - mlib_ImageAffine_BL_F32.c \ - mlib_ImageAffine_BL_S32.c \ - mlib_ImageAffine_NN.c \ - mlib_ImageAffine_NN_Bit.c \ - mlib_ImageFilters.c \ - mlib_ImageScanPoly.c \ - mlib_ImageConv_8nw.c \ - mlib_ImageConv_8ext.c \ - mlib_ImageConv_16nw.c \ - mlib_ImageConv_16ext.c \ - mlib_ImageConv_u16nw.c \ - mlib_ImageConv_u16ext.c \ - mlib_ImageConv_32nw.c \ - mlib_ImageConv_F32nw.c \ - mlib_ImageConvMxN_Fp.c \ - mlib_ImageConvMxN_ext.c \ - mlib_ImageConv_D64nw.c \ - mlib_ImageClipping.c \ - mlib_ImageConvCopyEdge_Bit.c \ - mlib_ImageConvClearEdge_Bit.c \ - mlib_ImageConv2x2_f.c \ - mlib_ImageConvClearEdge_Fp.c \ - mlib_v_ImageConvMxN_8.c \ - mlib_v_ImageConvClearEdge.c \ - mlib_v_ImageConvCopyEdge.c \ - mlib_v_ImageConvMxN_8ext.c \ - mlib_v_ImageConvVersion.c \ - mlib_v_ImageConv_8nw.c \ - mlib_ImageConvCopyEdge_Fp.c \ - mlib_v_ImageChannelInsert_1.c \ - mlib_v_ImageChannelExtract_43.c \ - mlib_v_ImageChannelExtract_1.c \ - mlib_ImageCopy_Bit.c \ - mlib_v_ImageCopy_f.c \ - mlib_ImageUtils.c \ - mlib_ImageDivTables.c - - BUILD_LIBMLIB_V_CFLAGS := $(filter-out -DMLIB_NO_LIBSUNMATH, $(BUILD_LIBMLIB_CFLAGS)) - - $(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE_V, \ - LIBRARY := mlib_image_v, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/awt/medialib \ - $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib, \ - LANG := C, \ - INCLUDE_FILES := $(BUILD_LIBMLIB_IMAGE_V_FILES), \ - OPTIMIZATION := HIGHEST, \ - CFLAGS := -xarch=sparcvis \ - $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib/vis_$(OPENJDK_TARGET_CPU_BITS).il \ - $(BUILD_LIBMLIB_V_CFLAGS) \ - $(CFLAGS_JDKLIB), \ - MAPFILE := $(BUILD_LIBMLIB_IMAGE_MAPFILE), \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(BUILD_LIBMLIB_LDLIBS) -ljava -ljvm \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libmlib_image_v, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBMLIB_IMAGE_V): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBMLIB_IMAGE_V) - -endif - -########################################################################################## - -LIBAWT_DIRS := \ - $(JDK_TOPDIR)/src/share/native/sun/awt \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ - $(JDK_TOPDIR)/src/share/native/sun/awt/image \ - $(JDK_TOPDIR)/src/share/native/sun/awt/image/gif \ - $(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - $(JDK_TOPDIR)/src/share/native/sun/awt/medialib \ - $(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - $(JDK_TOPDIR)/src/share/native/sun/awt/utility \ - $(JDK_TOPDIR)/src/share/native/sun/java2d \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ - $(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ - $(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ - $(JDK_TOPDIR)/src/share/native/sun/awt/image \ - $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/share/native/sun/font - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBAWT_DIRS += \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d -else - LIBAWT_DIRS += \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 -endif - -LIBAWT_CFLAGS += -D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \ - $(X_CFLAGS) \ - $(foreach dir, $(LIBAWT_DIRS), -I$(dir)) - -LIBAWT_FILES := \ - gifdecoder.c \ - imageInitIDs.c \ - img_globals.c \ - SurfaceData.c \ - Region.c \ - BufImgSurfaceData.c \ - Disposer.c \ - Trace.c \ - GraphicsPrimitiveMgr.c \ - Blit.c \ - BlitBg.c \ - ScaledBlit.c \ - FillRect.c \ - FillSpans.c \ - FillParallelogram.c \ - DrawParallelogram.c \ - DrawLine.c \ - DrawRect.c \ - DrawPolygons.c \ - DrawPath.c \ - FillPath.c \ - ProcessPath.c \ - MaskBlit.c \ - MaskFill.c \ - TransformHelper.c \ - AlphaMath.c \ - AlphaMacros.c \ - AnyByte.c \ - ByteBinary1Bit.c \ - ByteBinary2Bit.c \ - ByteBinary4Bit.c \ - ByteIndexed.c \ - ByteGray.c \ - Index8Gray.c \ - Index12Gray.c \ - AnyShort.c \ - Ushort555Rgb.c \ - Ushort565Rgb.c \ - Ushort4444Argb.c \ - Ushort555Rgbx.c \ - UshortGray.c \ - UshortIndexed.c \ - Any3Byte.c \ - ThreeByteBgr.c \ - AnyInt.c \ - IntArgb.c \ - IntArgbPre.c \ - IntArgbBm.c \ - IntRgb.c \ - IntBgr.c \ - IntRgbx.c \ - Any4Byte.c \ - FourByteAbgr.c \ - FourByteAbgrPre.c \ - BufferedMaskBlit.c \ - BufferedRenderPipe.c \ - ShapeSpanIterator.c \ - SpanClipRenderer.c \ - awt_ImageRep.c \ - awt_ImagingLib.c \ - awt_Mlib.c \ - awt_parseImage.c \ - DataBufferNative.c \ - dither.c \ - debug_assert.c \ - debug_mem.c \ - debug_trace.c \ - debug_util.c - -ifneq (, $(filter $(OPENJDK_TARGET_OS), solaris linux)) - LIBAWT_FILES += awt_LoadLibrary.c initIDs.c img_colors.c -endif - -ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBAWT_FILES += awt_LoadLibrary.c img_colors.c - LIBAWT_DIRS += $(JDK_TOPDIR)/src/macosx/native/com/apple/resources - LIBAWT_FILES += awt_LoadLibrary.c MacOSXResourceBundle.m - LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks - - LIBAWT_MacOSXResourceBundle.m_CFLAGS := -O0 -endif - -ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) - LIBAWT_CFLAGS += -DMLIB_ADD_SUFF - LIBAWT_CFLAGS += -xarch=sparcvis - LIBAWT_CFLAGS += $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib/vis_$(OPENJDK_TARGET_CPU_BITS).il - LIBAWT_CFLAGS += \ - -I$(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib \ - -I$(JDK_TOPDIR)/src/solaris/native/sun/java2d/medialib \ - -I$(JDK_TOPDIR)/src/solaris/native/sun/java2d/loops - - LIBAWT_DIRS += $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib \ - $(JDK_TOPDIR)/src/solaris/native/sun/java2d/loops - - LIBAWT_FILES += \ - vis_FuncArray.c \ - java2d_Mlib.c \ - mlib_ImageCreate.c \ - mlib_ImageZoom_NN.c \ - mlib_ImageCopy_Bit.c \ - mlib_sys.c \ - mlib_v_ImageClear.c \ - mlib_v_ImageClear_f.c \ - mlib_v_ImageConstXor.c \ - mlib_v_ImageCopy.c \ - mlib_v_ImageCopy_f.c \ - mlib_v_ImageXor.c \ - mlib_v_ImageZoom_NN_f.c \ - vis_Interp.c \ - vis_AlphaMacros.c \ - vis_AlphaMaskBlit.c \ - vis_AlphaMaskFill.c \ - vis_ByteGray.c \ - vis_ByteGray_FromRgb.c \ - vis_ByteGray_Mask.c \ - vis_ByteIndexed.c \ - vis_DrawLine.c \ - vis_FourByteAbgr.c \ - vis_IntArgb.c \ - vis_IntArgbPre.c \ - vis_IntArgbPre_Mask.c \ - vis_IntBgr.c \ - vis_IntRgb.c \ - vis_IntRgbx.c \ - vis_SrcMaskFill.c \ - vis_SrcOverMaskBlit.c \ - vis_SrcOverMaskFill.c \ - vis_FourByteAbgrPre.c \ - vis_GlyphList.c \ - vis_GlyphListXor.c \ - vis_IntArgbBm.c \ - vis_ThreeByteBgr.c \ - vis_UshortGray.c \ - vis_UshortGray_FromRgb.c \ - vis_XorBlit.c \ - mlib_v_ImageCopy_blk.s - - ifeq ($(OPENJDK_TARGET_CPU), sparcv9) - LIBAWT_ASFLAGS = -P -xarch=v9a - else - LIBAWT_ASFLAGS = -P -xarch=v8plusa - endif -else - LIBAWT_FILES += MapAccelFunc.c -endif - -ifneq ($(OPENJDK_TARGET_OS), solaris) - LIBAWT_CFLAGS += -DMLIB_NO_LIBSUNMATH -endif - -LIBAWT_LANG := C - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBAWT_FILES += AccelGlyphCache.c \ - ShaderList.c \ - CmdIDList.cpp \ - Hashtable.cpp \ - GDIHashtable.cpp \ - Devices.cpp \ - ObjectList.cpp \ - GDIBlitLoops.cpp \ - GDIRenderer.cpp \ - GDIWindowSurfaceData.cpp \ - WindowsFlags.cpp \ - WPrinterJob.cpp \ - awt_%.cpp \ - D3DBlitLoops.cpp \ - D3DBufImgOps.cpp \ - D3DContext.cpp \ - D3DGlyphCache.cpp \ - D3DGraphicsDevice.cpp \ - D3DMaskBlit.cpp \ - D3DMaskCache.cpp \ - D3DMaskFill.cpp \ - D3DPipelineManager.cpp \ - D3DPaints.cpp \ - D3DRenderer.cpp \ - D3DRenderQueue.cpp \ - D3DResourceManager.cpp \ - D3DSurfaceData.cpp \ - D3DTextRenderer.cpp \ - D3DVertexCacher.cpp \ - ShellFolder2.cpp \ - ThemeReader.cpp \ - ComCtl32Util.cpp \ - DllUtil.cpp \ - initIDs.cpp \ - MouseInfo.cpp \ - rect.c \ - OGLBlitLoops.c \ - OGLBufImgOps.c \ - OGLContext.c \ - OGLFuncs.c \ - OGLMaskBlit.c \ - OGLMaskFill.c \ - OGLPaints.c \ - OGLRenderQueue.c \ - OGLRenderer.c \ - OGLSurfaceData.c \ - OGLTextRenderer.c \ - OGLVertexCache.c \ - WGLGraphicsConfig.c \ - WGLSurfaceData.c - - LIBAWT_LANG := C++ - LIBAWT_CFLAGS += -EHsc -DUNICODE -D_UNICODE - ifeq ($(OPENJDK_TARGET_CPU_BITS), 64) - LIBAWT_CFLAGS += -DMLIB_OS64BIT - endif - - ifdef OPENJDK - LIBAWT_RC_FLAGS := -i "$(JDK_TOPDIR)/src/windows/resource/icons" - else - LIBAWT_RC_FLAGS := -i "$(JDK_TOPDIR)/src/closed/windows/native/sun/windows" - endif - LIBAWT_VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/native/sun/windows/awt.rc -endif - -ifeq ($(MILESTONE), internal) - LIBAWT_CFLAGS += -DINTERNAL_BUILD -endif - -LIBAWT_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libawt/mapfile-vers -ifeq ($(OPENJDK_TARGET_OS), linux) - LIBAWT_MAPFILE := -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \ - LIBRARY := awt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBAWT_DIRS), \ - INCLUDE_FILES := $(LIBAWT_FILES), \ - LANG := $(LIBAWT_LANG), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_CFLAGS), \ - ASFLAGS := $(LIBAWT_ASFLAGS), \ - MAPFILE := $(LIBAWT_MAPFILE), \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ - LDFLAGS_SUFFIX_linux := -ljvm $(LIBM) $(LIBDL) -ljava, \ - LDFLAGS_SUFFIX_solaris := -ljvm $(LIBM) $(LIBDL) -ljava -lc, \ - LDFLAGS_SUFFIX_macosx := -lmlib_image -ljvm $(LIBM) \ - -framework Cocoa \ - -framework OpenGL \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -framework JavaRuntimeSupport \ - -framework ApplicationServices \ - -framework AudioToolbox \ - -ljava, \ - LDFLAGS_SUFFIX_windows := kernel32.lib user32.lib gdi32.lib winspool.lib \ - imm32.lib ole32.lib uuid.lib shell32.lib \ - comdlg32.lib winmm.lib comctl32.lib shlwapi.lib \ - delayimp.lib jvm.lib $(WIN_JAVA_LIB) advapi32.lib \ - -DELAYLOAD:user32.dll -DELAYLOAD:gdi32.dll \ - -DELAYLOAD:shell32.dll -DELAYLOAD:winmm.dll \ - -DELAYLOAD:winspool.drv -DELAYLOAD:imm32.dll \ - -DELAYLOAD:ole32.dll -DELAYLOAD:comdlg32.dll \ - -DELAYLOAD:comctl32.dll -DELAYLOAD:shlwapi.dll, \ - VERSIONINFO_RESOURCE := $(LIBAWT_VERSIONINFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) $(LIBAWT_RC_FLAGS) \ - -D "JDK_FNAME=awt.dll" \ - -D "JDK_INTERNAL_NAME=awt" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBAWT): $(BUILD_LIBJAVA) - -ifeq ($(OPENJDK_TARGET_OS), macosx) - $(BUILD_LIBAWT): $(BUILD_LIBMLIB_IMAGE) -endif - -BUILD_LIBRARIES += $(BUILD_LIBAWT) - -########################################################################################## - -# TODO!! -# Even though this variable as a general name, it is -# only used on macos, in fontpath.c, as prefix for where to find fonts. -# -# It's used for libawt_headless _and_ libawt_xawt -# -X11_PATH := /usr/X11R6 - -ifneq ($(OPENJDK_TARGET_OS), windows) - ifndef BUILD_HEADLESS_ONLY - - LIBAWT_XAWT_DIRS := \ - $(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - $(JDK_TOPDIR)/src/share/native/sun/awt/utility \ - $(JDK_TOPDIR)/src/share/native/sun/font \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/font \ - $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/xawt \ - - LIBAWT_XAWT_CFLAGS := -DXAWT -DXAWT_HACK \ - -DX11_PATH=\"$(X11_PATH)\" -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ - $(CUPS_CFLAGS) \ - $(foreach dir, $(LIBAWT_XAWT_DIRS), -I$(dir)) \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga - - ifeq ($(OPENJDK_TARGET_OS), solaris) - LIBAWT_XAWT_CFLAGS += -DFUNCPROTO=15 - endif - - ifeq ($(OPENJDK_TARGET_OS), linux) - ifndef OPENJDK - include $(JDK_TOPDIR)/make/closed/xawt.gmk - endif - - ifeq ($(DISABLE_XRENDER), true) - LIBAWT_XAWT_CFLAGS += -DDISABLE_XRENDER_BY_DEFAULT=true - endif - endif - - ifeq ($(MILESTONE), internal) - LIBAWT_XAWT_CFLAGS += -DINTERNAL_BUILD - endif - - LIBAWT_XAWT_FILES := \ - XlibWrapper.c \ - XWindow.c \ - XToolkit.c \ - X11Color.c \ - X11SurfaceData.c \ - awt_GraphicsEnv.c \ - awt_InputMethod.c \ - robot_common.c \ - awt_Robot.c \ - list.c \ - multiVis.c \ - initIDs.c \ - awt_util.c \ - awt_Desktop.c \ - awt_UNIXToolkit.c \ - X11FontScaler_md.c \ - X11TextRenderer_md.c \ - fontpath.c \ - awt_Insets.c \ - awt_Event.c \ - X11Renderer.c \ - X11PMBlitLoops.c \ - OGLBlitLoops.c \ - OGLBufImgOps.c \ - OGLContext.c \ - OGLFuncs.c \ - OGLMaskBlit.c \ - OGLMaskFill.c \ - OGLPaints.c \ - OGLRenderQueue.c \ - OGLRenderer.c \ - OGLSurfaceData.c \ - OGLTextRenderer.c \ - OGLVertexCache.c \ - GLXGraphicsConfig.c \ - GLXSurfaceData.c \ - AccelGlyphCache.c \ - awt_Font.c \ - multi_font.c \ - awt_AWTEvent.c \ - awt_DrawingSurface.c \ - jawt.c \ - CUPSfuncs.c \ - debug_assert.c \ - debug_mem.c \ - debug_trace.c \ - debug_util.c \ - awt_Plugin.c \ - gnome_interface.c \ - gtk2_interface.c \ - swing_GTKEngine.c \ - swing_GTKStyle.c \ - rect.c \ - sun_awt_X11_GtkFileDialogPeer.c \ - XRSurfaceData.c \ - XRBackendNative.c - - LIBAWT_XAWT_LDFLAGS_SUFFIX := $(LIBM) -lawt -lXext -lX11 -lXrender $(LIBDL) -lXtst -lXi -ljava -ljvm -lc - - ifeq ($(OPENJDK_TARGET_OS), linux) - # To match old build, add this to LDFLAGS instead of suffix. - LIBAWT_XAWT_LDFLAGS += -lpthread - endif - - ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBAWT_XAWT_LDFLAGS_SUFFIX += -lpthread - endif - - # On macosx, the shared library origin is set twice for this lib. - $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_XAWT, \ - LIBRARY := awt_xawt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBAWT_XAWT_DIRS), \ - INCLUDE_FILES := $(LIBAWT_XAWT_FILES), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_XAWT_CFLAGS) \ - $(X_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libawt_xawt/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(X_LIBS) $(LIBAWT_XAWT_LDFLAGS), \ - LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_solaris := -L$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) \ - -R$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) \ - -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(call SET_SHARED_LIBRARY_ORIGIN). \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(call SET_SHARED_LIBRARY_ORIGIN)., \ - LDFLAGS_SUFFIX := $(LIBAWT_XAWT_LDFLAGS_SUFFIX), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=xawt.dll" \ - -D "JDK_INTERNAL_NAME=xawt" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_xawt, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBAWT_XAWT): $(BUILD_LIBJAVA) - - $(BUILD_LIBAWT_XAWT): $(BUILD_LIBAWT) - - BUILD_LIBRARIES += $(BUILD_LIBAWT_XAWT) - - endif -endif - -########################################################################################## - -BUILD_LIBZIP_EXCLUDES := -ifeq ($(USE_EXTERNAL_LIBZ), true) - LIBZ := -lz - LIBZIP_EXCLUDES += zlib-1.2.5 -else - ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 -endif - -BUILD_LIBZIP_REORDER := -ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - BUILD_LIBZIP_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU) - endif -endif - -ifeq ($(LIBZIP_CAN_USE_MMAP), true) - BUILD_LIBZIP_MMAP := -DUSE_MMAP -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \ - LIBRARY := zip, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip, \ - EXCLUDES := $(LIBZIP_EXCLUDES), \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(ZLIB_CPPFLAGS) \ - -I$(JDK_TOPDIR)/src/share/native/java/io \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io, \ - CFLAGS_posix := $(BUILD_LIBZIP_MMAP) -UDEBUG, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libzip/mapfile-vers, \ - REORDER := $(BUILD_LIBZIP_REORDER), \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(EXPORT_ZIP_FUNCS), \ - LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \ - -export:ZIP_ReadEntry -export:ZIP_GetNextEntry jvm.lib \ - $(WIN_JAVA_LIB), \ - LDFLAGS_SUFFIX_linux := -ljvm -ljava $(LIBZ), \ - LDFLAGS_SUFFIX_solaris := -ljvm -ljava $(LIBZ) -lc, \ - LDFLAGS_SUFFIX_macosx := $(LIBZ) -ljava -ljvm, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=zip.dll" \ - -D "JDK_INTERNAL_NAME=zip" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libzip, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - -$(BUILD_LIBZIP): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBZIP) - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \ - LIBRARY := unpack, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/com/sun/java/util/jar/pack, \ - EXCLUDE_FILES := main.cpp, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CXXFLAGS_JDKLIB) \ - -DNO_ZLIB -DUNPACK_JNI -DFULL, \ - CFLAGS_release := -DPRODUCT, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libunpack/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := -map:$(JDK_OUTPUTDIR)/objs/unpack.map -debug \ - jvm.lib $(WIN_JAVA_LIB), \ - LDFLAGS_SUFFIX_posix := -ljvm $(LIBCXX) -ljava -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libunpack, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=unpack.dll" \ - -D "JDK_INTERNAL_NAME=unpack" \ - -D "JDK_FTYPE=0x2L", \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBUNPACK): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBUNPACK) - -ifeq ($(OPENJDK_TARGET_OS), windows) - $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)unpack.map: $(BUILD_LIBUNPACK) - $(ECHO) Copying $(@F) - $(CP) $(patsubst %$(SHARED_LIBRARY_SUFFIX), %.map, $<) $@ - - $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)unpack.pdb: $(BUILD_LIBUNPACK) - $(ECHO) Copying $(@F) - $(CP) $(patsubst %$(SHARED_LIBRARY_SUFFIX), %.pdb, $<) $@ -endif - -########################################################################################## - -LIBATTACH_EXCLUDE_FILES := -ifneq ($(OPENJDK_TARGET_OS), solaris) - LIBATTACH_EXCLUDE_FILES += SolarisVirtualMachine.c -endif -ifneq ($(OPENJDK_TARGET_OS), linux) - LIBATTACH_EXCLUDE_FILES += LinuxVirtualMachine.c -endif -ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBATTACH_EXCLUDE_FILES += BsdVirtualMachine.c -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \ - LIBRARY := attach, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/tools/attach, \ - EXCLUDE_FILES := $(LIBATTACH_EXCLUDE_FILES), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB), \ - CFLAGS_windows := /Gy, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=attach.dll" \ - -D "JDK_INTERNAL_NAME=attach" \ - -D "JDK_FTYPE=0x2L", \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := -ldoor, \ - LDFLAGS_windows := /ORDER:@$(JDK_TOPDIR)/makefiles/mapfiles/libattach/reorder-windows-$(OPENJDK_TARGET_CPU), \ - LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ - LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib psapi.lib, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libattach, \ - DEBUG_SYMBOLS := true)) - -$(BUILD_LIBATTACH): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBATTACH) - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBDT_SOCKET, \ - LIBRARY := dt_socket, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/transport/socket \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/socket, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \ - -I$(INCLUDEDIR) -I$(JDK_OUTPUTDIR)/include/$(OPENJDK_TARGET_OS) \ - -I$(JDK_TOPDIR)/src/share/transport/socket \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/socket \ - -I$(JDK_TOPDIR)/src/share/back/export \ - -I$(JDK_TOPDIR)/src/share/back, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libdt_socket/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := -lpthread, \ - LDFLAGS_SUFFIX_solaris := -lnsl -lsocket -lc, \ - LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX) -export:jdwpTransport_OnLoad ws2_32.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=dt_socket.dll" \ - -D "JDK_INTERNAL_NAME=dt_socket" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libdt_socket, \ - DEBUG_SYMBOLS := true)) - -$(BUILD_LIBDT_SOCKET): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBDT_SOCKET) - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), windows) - - $(eval $(call SetupNativeCompilation,BUILD_LIBDT_SHMEM, \ - LIBRARY := dt_shmem, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/com/sun/tools/jdi \ - $(JDK_TOPDIR)/src/share/transport/shmem \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/shmem, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \ - -I$(INCLUDEDIR) -I$(JDK_OUTPUTDIR)/include/$(OPENJDK_TARGET_OS) \ - -I$(JDK_TOPDIR)/src/share/transport/shmem \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/shmem \ - -I$(JDK_TOPDIR)/src/share/back/export, \ - LDFLAGS := $(LDFLAGS_JDKLIB), \ - LDFLAGS_windows := -export:jdwpTransport_OnLoad, \ - LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=dt_shmem.dll" \ - -D "JDK_INTERNAL_NAME=dt_shmem" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libdt_shmem, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBDT_SHMEM) - -endif # OPENJDK_TARGET_OS - -########################################################################################## -# JDWP_LOGGING causes log messages to be compiled into the library. -$(eval $(call SetupNativeCompilation,BUILD_LIBJDWP, \ - LIBRARY := jdwp, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/back $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/back, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) -DJDWP_LOGGING \ - -I$(JDK_TOPDIR)/src/share/transport/export \ - -I$(JDK_TOPDIR)/src/share/back/export \ - -I$(JDK_TOPDIR)/src/share/npt \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \ - -I$(JDK_TOPDIR)/src/share/back \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/back \ - -I$(JDK_OUTPUTDIR)/gensrc_jdwp_headers, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjdwp/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := $(LIBDL) -lc, \ - LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jdwp.dll" \ - -D "JDK_INTERNAL_NAME=jdwp" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjdwp, \ - DEBUG_SYMBOLS := true)) - -$(BUILD_LIBJDWP): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBJDWP) - -########################################################################################## - -LIBJAAS_MAPFILE := -ifneq ($(OPENJDK_TARGET_OS), solaris) - LIBJAAS_EXCLUDE_FILES := Solaris.c -else - # only on solaris...wonder why - LIBJAAS_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjaas/mapfile-vers -endif - -LIBJAAS_NAME := jaas_unix -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBJAAS_NAME := jaas_nt -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \ - LIBRARY := $(LIBJAAS_NAME), \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/com/sun/security/auth/module, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB), \ - MAPFILE := $(LIBJAAS_MAPFILE), \ - LDFLAGS := $(filter-out -ljava, $(LDFLAGS_JDKLIB)) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \ - LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - EXCLUDE_FILES := $(LIBJAAS_EXCLUDE_FILES), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=$(LIBJAAS_NAME).dll" \ - -D "JDK_INTERNAL_NAME=$(LIBJAAS_NAME)" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjaas, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBJAAS): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBJAAS) - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBJSDT, \ - LIBRARY := jsdt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/tracing/dtrace \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/tracing/dtrace, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/sun/tracing/dtrace, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjsdt/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := $(LIBDL), \ - LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX) $(LIBDL), \ - LDFLAGS_SUFFIX_macosx := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jsdt.dll" \ - -D "JDK_INTERNAL_NAME=jsdt" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsdt, \ - DEBUG_SYMBOLS := true)) - -$(BUILD_LIBJSDT): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBJSDT) - -########################################################################################## - -# TODO: Update awt lib path when awt is converted -$(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \ - LIBRARY := lcms, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms, \ - LANG := C, \ - OPTIMIZATION := HIGHEST, \ - CFLAGS := $(filter-out -xc99=%none, $(CFLAGS_JDKLIB)) \ - $(SHARED_LIBRARY_FLAGS) \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug, \ - CFLAGS_solaris := -xc99=no_lib, \ - CFLAGS_windows := -DCMS_IS_WINDOWS_, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/liblcms/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := /usr/lib$(OPENJDK_TARGET_CPU_ISADIR)/libm.so.2, \ - LDFLAGS_windows := $(WIN_AWT_LIB) $(WIN_JAVA_LIB), \ - LDFLAGS_SUFFIX_solaris := -lawt -ljava -ljvm -lc, \ - LDFLAGS_SUFFIX_macosx := $(LIBM) -lawt -ljava -ljvm, \ - LDFLAGS_SUFFIX_linux := -lm -lawt -ljava -ljvm, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=lcms.dll" \ - -D "JDK_INTERNAL_NAME=lcms" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/liblcms, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -BUILD_LIBRARIES += $(BUILD_LIBLCMS) - -$(BUILD_LIBLCMS): $(BUILD_LIBAWT) - -########################################################################################## - -ifdef OPENJDK - BUILD_LIBJPEG_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjpeg/mapfile-vers -else - BUILD_LIBJPEG_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjpeg/mapfile-vers-closed - BUILD_LIBJPEG_CLOSED_SRC := $(JDK_TOPDIR)/src/closed/share/native/sun/awt/image/jpeg - BUILD_LIBJPEG_CLOSED_INCLUDES := -I$(BUILD_LIBJPEG_CLOSED_SRC) -endif - -BUILD_LIBJPEG_REORDER := -ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - BUILD_LIBJPEG_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libjpeg/reorder-$(OPENJDK_TARGET_CPU) - endif -endif - -# Suppress gcc warnings like "variable might be clobbered by 'longjmp' -# or 'vfork'": this warning indicates that some variable is placed to -# a register by optimized compiler and it's value might be lost on longjmp(). -# Recommended way to avoid such warning is to declare the variable as -# volatile to prevent the optimization. However, this approach does not -# work because we have to declare all variables as volatile in result. -#ifndef CROSS_COMPILE_ARCH -# CC_43_OR_NEWER := \ -# $(shell $(EXPR) $(CC_MAJORVER) \> 4 \| \ -# \( $(CC_MAJORVER) = 4 \& $(CC_MINORVER) \>= 3 \) ) -# ifeq ($(CC_43_OR_NEWER), 1) -# BUILD_LIBJPEG_CFLAGS_linux += -Wno-clobbered -# endif -#endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBJPEG, \ - LIBRARY := jpeg, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBJPEG_CLOSED_SRC) \ - $(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg, \ - LANG := C, \ - OPTIMIZATION := HIGHEST, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(BUILD_LIBJPEG_CLOSED_INCLUDES) \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg, \ - MAPFILE := $(BUILD_LIBJPEG_MAPFILE), \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := $(WIN_JAVA_LIB) jvm.lib, \ - LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jpeg.dll" \ - -D "JDK_INTERNAL_NAME=jpeg" \ - -D "JDK_FTYPE=0x2L", \ - REORDER := $(BUILD_LIBJPEG_REORDER), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjpeg, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBJPEG): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBJPEG) - -########################################################################################## - -ifndef OPENJDK - FONT_HEADERS := -I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k - BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libfontmanager/mapfile-vers - LIBFONTMANAGER_EXCLUDE_FILES += freetypeScaler.c -else - FONT_HEADERS := $(FREETYPE2_CFLAGS) - BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libfontmanager/mapfile-vers.openjdk - BUILD_LIBFONTMANAGER_FONTLIB := $(FREETYPE2_LIBS) -endif - -LIBFONTMANAGER_OPTIMIZATION := HIGH - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBFONTMANAGER_EXCLUDE_FILES += X11FontScaler.c \ - X11TextRenderer.c - LIBFONTMANAGER_OPTIMIZATION := HIGHEST -else - LIBFONTMANAGER_EXCLUDE_FILES += fontpath.c \ - lcdglyph.c -endif - -BUILD_LIBFONTMANAGER_CFLAGS_COMMON := \ - $(X_CFLAGS) \ - -DLE_STANDALONE -DHEADLESS \ - $(FONT_HEADERS) \ - -I$(JDK_TOPDIR)/src/share/native/sun/font \ - -I$(JDK_TOPDIR)/src/share/native/sun/font/layout \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d - -# Turn off aliasing with GCC for ExtensionSubtables.cpp -ifeq ($(OPENJDK_TARGET_OS), linux) - BUILD_LIBFONTMANAGER_ExtensionSubtables.cpp_CXXFLAGS := -fno-strict-aliasing -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \ - LIBRARY := fontmanager, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/font \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/font, \ - EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \ - AccelGlyphCache.c, \ - LANG := C++, \ - CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBFONTMANAGER_CFLAGS_COMMON), \ - CXXFLAGS := $(CXXFLAGS_JDKLIB) $(BUILD_LIBFONTMANAGER_CFLAGS_COMMON), \ - OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \ - CFLAGS_windows = -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ - -DCC_NOEX, \ - MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \ - LDFLAGS := $(subst -Xlinker -z -Xlinker defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \ - LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ - LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \ - LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \ - -ljava -ljvm, \ - LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \ - $(WIN_AWT_LIB), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=fontmanager.dll" \ - -D "JDK_INTERNAL_NAME=fontmanager" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfontmanager, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT) - -ifneq (, $(findstring $(OPENJDK_TARGET_OS), solaris macosx)) - $(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT_XAWT) -endif - -BUILD_LIBRARIES += $(BUILD_LIBFONTMANAGER) - -########################################################################################## - -ifndef OPENJDK - - #ifeq ($(OPENJDK_TARGET_OS), linux) - # ifeq ("$(CC_VER_MAJOR)", "3") - # OTHER_LDLIBS += -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic - # endif - #endif - # - # The resulting size of the t2k lib file is (at least on linux) dependant on the order of - # the input .o files. Because of this the new build will differ in size to the old build. - BUILD_LIBT2K_CFLAGS_COMMON := -I$(JDK_TOPDIR)/src/share/native/sun/font \ - -I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \ - -I$(JDK_TOPDIR)/src/closed/share/native/sun/font \ - -I$(JDK_TOPDIR)/src/share/share/native/sun/font \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/font \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d - - $(eval $(call SetupNativeCompilation,BUILD_LIBT2K, \ - LIBRARY := t2k, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/closed/share/native/sun/font \ - $(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \ - $(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k/ttHints, \ - EXCLUDE_FILES := orion.c, \ - LANG := C++, \ - OPTIMIZATION := HIGH, \ - CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBT2K_CFLAGS_COMMON), \ - CXXFLAGS := $(CXXFLAGS_JDKLIB) $(BUILD_LIBT2K_CFLAGS_COMMON), \ - CFLAGS_windows = -DCC_NOEX, \ - CXXFLAGS_windows = -DCC_NOEX, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libt2k/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := user32.lib $(JDK_OUTPUTDIR)/objs/libfontmanager/fontmanager.lib, \ - LDFLAGS_SUFFIX_posix := $(LIBM) $(LIBCXX) -lfontmanager -ljava -ljvm -lc, \ - LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=t2k.dll" \ - -D "JDK_INTERNAL_NAME=t2k" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libt2k, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - # t2k is linked against fontmanager - $(BUILD_LIBT2K): $(BUILD_LIBFONTMANAGER) - - BUILD_LIBRARIES += $(BUILD_LIBT2K) -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), windows) - ifeq ($(OPENJDK_TARGET_CPU), x86) - KERNEL32_LIB := kernel32.lib - endif - $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \ - LIBRARY := jawt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows, \ - INCLUDE_FILES := jawt.cpp, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CXXFLAGS_JDKLIB) \ - -EHsc -DUNICODE -D_UNICODE \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \ - advapi32.lib $(WIN_AWT_LIB), \ - LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jawt.dll" \ - -D "JDK_INTERNAL_NAME=jawt" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawt, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBJAWT): $(BUILD_LIBAWT) - - $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX): $(BUILD_LIBJAWT) - $(ECHO) Copying $(@F) - $(CP) $(JDK_OUTPUTDIR)/objs/libjawt/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX) $@ - - BUILD_LIBRARIES += $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX) - -else # OPENJDK_TARGET_OS not windows - - JAWT_LIBS := - ifneq ($(OPENJDK_TARGET_OS), solaris) - JAWT_LIBS += -lawt - endif - - ifndef BUILD_HEADLESS_ONLY - JAWT_LIBS += -lawt_xawt - else - JAWT_LIBS += -lawt_headless - HEADLESS_CFLAG += -DHEADLESS - endif - - JAWT_FILES := jawt.c - ifeq ($(OPENJDK_TARGET_OS), macosx) - JAWT_FILES := jawt.m - JAWT_LIBS := -lawt_lwawt - endif - - $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \ - LIBRARY := jawt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ - $(JDK_TOPDIR)/src/macosx/native/sun/awt, \ - INCLUDE_FILES := $(JAWT_FILES), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB), \ - CFLAGS_linux := $(HEADLESS_CFLAG), \ - CFLAGS_macosx := -I$(JDK_TOPDIR)/src/solaris/native/sun/awt, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjawt/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := -L$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ - LDFLAGS_SUFFIX_linux := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX), \ - LDFLAGS_SUFFIX_solaris := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX) -lXrender, \ - LDFLAGS_SUFFIX_macosx := -Xlinker -rpath -Xlinker @loader_path $(JAWT_LIBS) \ - -framework Cocoa $(LDFLAGS_JDKLIB_SUFFIX), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawt, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - ifndef BUILD_HEADLESS_ONLY - $(BUILD_LIBJAWT): $(BUILD_LIBAWT_XAWT) - else - $(BUILD_LIBJAWT): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)awt_headless$(SHARED_LIBRARY_SUFFIX) - endif - - ifeq ($(OPENJDK_TARGET_OS), macosx) - $(BUILD_LIBJAWT): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)awt_lwawt$(SHARED_LIBRARY_SUFFIX) - endif - -endif # OPENJDK_TARGET_OS - -BUILD_LIBRARIES += $(BUILD_LIBJAWT) - -########################################################################################## - -LIBINSTRUMENT_SRC := $(JDK_TOPDIR)/src/share/instrument \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/instrument - -LIBINSTRUMENT_FILES := \ - EncodingSupport.c \ - EncodingSupport_md.c \ - FileSystemSupport_md.c \ - InstrumentationImplNativeMethods.c \ - InvocationAdapter.c \ - JarFacade.c \ - JPLISAgent.c \ - JPLISAssert.c \ - JavaExceptions.c \ - PathCharsValidator.c \ - Reentrancy.c \ - Utilities.c \ - canonicalize_md.c - -LIBINSTRUMENT_DIR := $(JDK_OUTPUTDIR)/objs/libinstrument -LIBINSTRUMENT_CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/instrument \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/instrument \ - -I$(JDK_TOPDIR)/src/share/bin - -LIBINSTRUMENT_LDFLAGS := -LIBINSTRUMENT_LDFLAGS_SUFFIX := - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBINSTRUMENT_LDFLAGS += $(JDK_OUTPUTDIR)/objs/jli_static.lib $(WIN_JAVA_LIB) \ - -export:Agent_OnAttach advapi32.lib - # Statically link the C runtime so that there are not dependencies on modules - # not on the search patch when invoked from the Windows system directory - # (or elsewhere). - LIBINSTRUMENT_CFLAGS := $(filter-out -MD, $(LIBINSTRUMENT_CFLAGS)) - # equivalent of strcasecmp is stricmp on Windows - LIBINSTRUMENT_CFLAGS += -Dstrcasecmp=stricmp -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBINSTRUMENT, \ - LIBRARY := instrument, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBINSTRUMENT_SRC), \ - INCLUDE_FILES := $(LIBINSTRUMENT_FILES), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(LIBINSTRUMENT_CFLAGS), \ - CFLAGS_debug := -DJPLIS_LOGGING, \ - CFLAGS_release := -DNO_JPLIS_LOGGING, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libinstrument/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(LIBINSTRUMENT_LDFLAGS), \ - LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/jli), \ - LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/jli), \ - LDFLAGS_macosx := -Xlinker -all_load $(JDK_OUTPUTDIR)/objs/libjli_static.a \ - -framework Cocoa -framework Security -framework ApplicationServices, \ - LDFLAGS_SUFFIX := $(LIBINSTRUMENT_LDFLAGS_SUFFIX), \ - LDFLAGS_SUFFIX_macosx := -liconv $(LIBZ), \ - LDFLAGS_SUFFIX_solaris := $(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL) -lc, \ - LDFLAGS_SUFFIX_linux := $(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=instrument.dll" \ - -D "JDK_INTERNAL_NAME=instrument" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(LIBINSTRUMENT_DIR), \ - DEBUG_SYMBOLS := true)) - -ifneq (, $(findstring $(OPENJDK_TARGET_OS), macosx windows)) - $(BUILD_LIBINSTRUMENT): $(JDK_OUTPUTDIR)/objs/$(LIBRARY_PREFIX)jli_static$(STATIC_LIBRARY_SUFFIX) -else - $(BUILD_LIBINSTRUMENT): $(INSTALL_LIBRARIES_HERE)/jli/$(LIBRARY_PREFIX)jli$(SHARED_LIBRARY_SUFFIX) -endif -$(BUILD_LIBINSTRUMENT): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBINSTRUMENT) - -########################################################################################## - -BUILD_LIBMANAGEMENT_SRC := $(JDK_TOPDIR)/src/share/native/sun/management \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/management \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/com/sun/management - -BUILD_LIBMANAGEMENT_EXCLUDES := - -BUILD_LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/management - -ifneq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBMANAGEMENT_EXCLUDES += OperatingSystem_md.c -else - BUILD_LIBMANAGEMENT_EXCLUDES += UnixOperatingSystem_md.c -endif - -ifneq ($(OPENJDK_TARGET_OS), solaris) - BUILD_LIBMANAGEMENT_EXCLUDES += SolarisOperatingSystem.c -endif - -ifneq ($(OPENJDK_TARGET_OS), linux) - BUILD_LIBMANAGEMENT_EXCLUDES += LinuxOperatingSystem.c -endif - -ifneq ($(OPENJDK_TARGET_OS), macosx) - BUILD_LIBMANAGEMENT_EXCLUDES += MacosxOperatingSystem.c -endif - -LIBMANAGEMENT_OPTIMIZATION := HIGH -ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) - ifeq ($(ENABLE_DEBUG_SYMBOLS), true) - LIBMANAGEMENT_OPTIMIZATION := LOW - endif -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \ - LIBRARY := management, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBMANAGEMENT_SRC), \ - EXCLUDE_FILES := $(BUILD_LIBMANAGEMENT_EXCLUDES), \ - LANG := C, \ - OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBMANAGEMENT_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libmanagement/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := -lkstat, \ - LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ - LDFLAGS_SUFFIX_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=management.dll" \ - -D "JDK_INTERNAL_NAME=management" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libmanagement, \ - DEBUG_SYMBOLS := true)) - -$(BUILD_LIBMANAGEMENT): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBMANAGEMENT) - -########################################################################################## - -BUILD_LIBHPROF_SRC := $(JDK_TOPDIR)/src/share/demo/jvmti/hprof $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/demo/jvmti/hprof -BUILD_LIBHPROF_CFLAGS := -I$(JDK_TOPDIR)/src/share/demo/jvmti/hprof \ - -I$(JDK_TOPDIR)/src/share/npt \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \ - -I$(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo - -BUILD_LIBHPROF_LDFLAGS := - -LIBHPROF_OPTIMIZATION := HIGHEST -ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) - ifeq ($(ENABLE_DEBUG_SYMBOLS), true) - LIBHPROF_OPTIMIZATION := LOW - endif -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBHPROF, \ - LIBRARY := hprof, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBHPROF_SRC), \ - LANG := C, \ - OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(BUILD_LIBHPROF_CFLAGS), \ - CFLAGS_debug := -DHPROF_LOGGING, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libhprof/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := wsock32.lib winmm.lib advapi32.lib, \ - LDFLAGS_SUFFIX_linux := $(LIBDL), \ - LDFLAGS_SUFFIX_macosx := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lsocket -lnsl $(LIBDL) -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=hprof.dll" \ - -D "JDK_INTERNAL_NAME=hprof" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libhprof_jvmti, \ - DEBUG_SYMBOLS := true)) - -BUILD_LIBRARIES += $(BUILD_LIBHPROF) - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA_CRW_DEMO, \ - LIBRARY := java_crw_demo, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjava_crw_demo/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=java_crw_demo.dll" \ - -D "JDK_INTERNAL_NAME=java_crw_demo" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjava_crw_demo, \ - DEBUG_SYMBOLS := true)) - -BUILD_LIBRARIES += $(BUILD_LIBJAVA_CRW_DEMO) - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBNPT, \ - LIBRARY := npt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/npt $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/npt \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnpt/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_macosx := -liconv, \ - LDFLAGS_SUFFIX_windows := -export:nptInitialize -export:nptTerminate, \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=npt.dll" \ - -D "JDK_INTERNAL_NAME=npt" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libnpt, \ - DEBUG_SYMBOLS := true)) - -BUILD_LIBRARIES += $(BUILD_LIBNPT) - -########################################################################################## - -LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/share/native/java/net \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/dns \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/spi - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/www/protocol/http/ntlm -else - LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/sdp -endif - -LIBNET_CFLAGS := $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir)) - -LIBNET_EXCLUDE_FILES := -ifneq ($(OPENJDK_TARGET_OS), linux) - LIBNET_EXCLUDE_FILES += linux_close.c -endif - -ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBNET_EXCLUDE_FILES += bsd_close.c -endif - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBNET_EXCLUDE_FILES += PlainSocketImpl.c PlainDatagramSocketImpl.c SdpSupport.c -else - LIBNET_EXCLUDE_FILES += TwoStacksPlainSocketImpl.c DualStackPlainSocketImpl.c \ - TwoStacksPlainDatagramSocketImpl.c DualStackPlainDatagramSocketImpl.c \ - NTLMAuthSequence.c NetworkInterface_winXP.c -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \ - LIBRARY := net, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBNET_SRC_DIRS), \ - EXCLUDE_FILES := $(LIBNET_EXCLUDE_FILES), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBNET_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnet/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_macosx := -ljvm -ljava, \ - LDFLAGS_SUFFIX_solaris := -ljvm -ljava -lnsl -lsocket $(LIBDL) -lc, \ - LDFLAGS_SUFFIX_linux := $(LIBDL) -ljvm -lpthread -ljava, \ - LDFLAGS_SUFFIX_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \ - delayimp.lib $(WIN_JAVA_LIB) advapi32.lib \ - -DELAYLOAD:secur32.dll -DELAYLOAD:iphlpapi.dll, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=net.dll" \ - -D "JDK_INTERNAL_NAME=net" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libnet, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBNET): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBNET) - -$(JDK_OUTPUTDIR)/lib/net.properties: $(JDK_TOPDIR)/src/share/lib/net.properties - $(ECHO) $(LOG_INFO) Copying $(@F) - $(call install-file) - -COPY_FILES += $(JDK_OUTPUTDIR)/lib/net.properties - -ifeq ($(OPENJDK_TARGET_OS), solaris) - $(JDK_OUTPUTDIR)/lib/sdp/sdp.conf.template: $(JDK_TOPDIR)/src/${OPENJDK_TARGET_OS_API_DIR}/lib/sdp/sdp.conf.template - $(ECHO) $(LOG_INFO) Copying $(@F) - $(call install-file) - - COPY_FILES += $(JDK_OUTPUTDIR)/lib/sdp/sdp.conf.template -endif - -########################################################################################## - -BUILD_LIBNIO_SRC := \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/nio \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/ch \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/fs - -BUILD_LIBNIO_CFLAGS := \ - -I$(JDK_TOPDIR)/src/share/native/sun/nio/ch \ - -I$(JDK_TOPDIR)/src/share/native/java/io \ - -I$(JDK_TOPDIR)/src/share/native/java/net \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net - -BUILD_LIBNIO_FILES := \ - DatagramChannelImpl.c \ - DatagramDispatcher.c \ - FileChannelImpl.c \ - FileDispatcherImpl.c \ - FileKey.c \ - IOUtil.c \ - MappedByteBuffer.c \ - Net.c \ - ServerSocketChannelImpl.c \ - SocketChannelImpl.c \ - SocketDispatcher.c - -ifeq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBNIO_FILES += \ - Iocp.c \ - RegistryFileTypeDetector.c \ - WindowsAsynchronousFileChannelImpl.c \ - WindowsAsynchronousServerSocketChannelImpl.c \ - WindowsAsynchronousSocketChannelImpl.c \ - WindowsNativeDispatcher.c \ - WindowsSelectorImpl.c -endif - -ifeq ($(OPENJDK_TARGET_OS), linux) - BUILD_LIBNIO_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS) - BUILD_LIBNIO_FILES += \ - EPoll.c \ - EPollArrayWrapper.c \ - EPollPort.c \ - InheritedChannel.c \ - NativeThread.c \ - PollArrayWrapper.c \ - UnixAsynchronousServerSocketChannelImpl.c \ - UnixAsynchronousSocketChannelImpl.c \ - GnomeFileTypeDetector.c \ - MagicFileTypeDetector.c \ - LinuxNativeDispatcher.c \ - LinuxWatchService.c \ - UnixCopyFile.c \ - UnixNativeDispatcher.c -endif - -ifeq ($(OPENJDK_TARGET_OS), macosx) - BUILD_LIBNIO_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS) - BUILD_LIBNIO_SRC += $(JDK_TOPDIR)/src/macosx/native/sun/nio/ch - BUILD_LIBNIO_FILES += \ - InheritedChannel.c \ - NativeThread.c \ - PollArrayWrapper.c \ - UnixAsynchronousServerSocketChannelImpl.c \ - UnixAsynchronousSocketChannelImpl.c \ - BsdNativeDispatcher.c \ - MacOSXNativeDispatcher.c \ - UnixCopyFile.c \ - UnixNativeDispatcher.c \ - KQueue.c \ - KQueuePort.c \ - KQueueArrayWrapper.c -endif - -ifeq ($(OPENJDK_TARGET_OS), solaris) - BUILD_LIBNIO_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS) - BUILD_LIBNIO_FILES += \ - DevPollArrayWrapper.c \ - InheritedChannel.c \ - NativeThread.c \ - PollArrayWrapper.c \ - SolarisEventPort.c \ - UnixAsynchronousServerSocketChannelImpl.c \ - UnixAsynchronousSocketChannelImpl.c \ - GnomeFileTypeDetector.c \ - SolarisNativeDispatcher.c \ - SolarisWatchService.c \ - UnixCopyFile.c \ - UnixNativeDispatcher.c -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \ - LIBRARY := nio, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBNIO_SRC), \ - INCLUDE_FILES := $(BUILD_LIBNIO_FILES), \ - LANG := C, \ - OPTIMIZATION := HIGH, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(BUILD_LIBNIO_CFLAGS), \ - MAPFILE := $(BUILD_LIBNIO_MAPFILE), \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(BUILD_LIBNIO_LDFLAGS) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := -ljava -lnet -lpthread $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -ljvm -lsocket -lposix4 $(LIBDL) \ - -lsendfile -ljava -lnet -lc, \ - LDFLAGS_SUFFIX_windows := jvm.lib ws2_32.lib $(WIN_JAVA_LIB) \ - $(JDK_OUTPUTDIR)/objs/libnet/net.lib \ - advapi32.lib, \ - LDFLAGS_SUFFIX_macosx := -ljava -lnet -pthread -framework CoreFoundation, \ - LDFLAGS_SUFFIX :=, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=nio.dll" \ - -D "JDK_INTERNAL_NAME=nio" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libnio, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -BUILD_LIBRARIES += $(BUILD_LIBNIO) - -$(BUILD_LIBNIO): $(BUILD_LIBNET) - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS_API), posix) - - ifneq ($(OPENJDK_TARGET_OS), macosx) - - SCTP_WERROR := -Werror - ifeq ($(OPENJDK_TARGET_CPU_ARCH), ppc) - SCTP_WERROR := - endif - - $(eval $(call SetupNativeCompilation,BUILD_LIBSCTP, \ - LIBRARY := sctp, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/ch/sctp, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/sun/nio/ch \ - -I$(JDK_TOPDIR)/src/share/native/sun/nio/ch/sctp \ - -I$(JDK_TOPDIR)/src/share/native/java/net \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/ch \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net, \ - CFLAGS_linux := $(SCTP_WERROR), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libsctp/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := -lpthread $(LIBDL) -ljava -ljvm, \ - LDFLAGS_SUFFIX_posix := -lnio -lnet, \ - LDFLAGS_SUFFIX_solaris := -lsocket -ljava -ljvm -lc, \ - LDFLAGS_SUFFIX_macosx := -ljava -ljvm, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsctp, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBSCTP) - - $(BUILD_LIBSCTP): $(BUILD_LIBNIO) - endif -endif - -########################################################################################## - -BUILD_LIBJLI_SRC_DIRS := $(JDK_TOPDIR)/src/share/bin $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/bin -LIBJLI_CFLAGS := $(CFLAGS_JDKLIB) $(foreach dir, $(BUILD_LIBJLI_SRC_DIRS), -I$(dir)) - -BUILD_LIBJLI_FILES := \ - java.c \ - splashscreen_stubs.c \ - parse_manifest.c \ - version_comp.c \ - wildcard.c \ - jli_util.c - -ifeq ($(JVM_VARIANT_ZERO), true) - ERGO_FAMILY := zero -else - ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86) - ERGO_FAMILY := i586 - else - ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH) - endif -endif - -ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBJLI_CFLAGS += -I$(JDK_TOPDIR)/src/macosx/bin - BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/bin - BUILD_LIBJLI_FILES += java_md_common.c java_md_macosx.c - - BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c - BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c -endif - -ifeq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBJLI_FILES += java_md.c \ - cmdtoargs.c - # Staticically link with c runtime on windows. - LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS)) -else ifneq ($(OPENJDK_TARGET_OS), macosx) - - BUILD_LIBJLI_FILES += java_md_common.c - BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c - - ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c - - # if the architecture specific ergo file exists then - # use it, else use the generic definitions from ergo.c - ifneq ($(wildcard $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/bin/$(ERGO_ARCH_FILE)), ) - BUILD_LIBJLI_FILES += $(ERGO_ARCH_FILE) - else # !ERGO_ARCH_FILE - LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO - endif # ERGO_ARCH_FILE -endif #WINDOWS - -# Append defines depending on target platform -LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS) - -ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" -endif - -ifneq ($(USE_EXTERNAL_LIBZ), true) - BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 - LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS) - BUILD_LIBJLI_FILES += \ - inflate.c \ - inftrees.c \ - inffast.c \ - zadler32.c \ - zcrc32.c \ - zutil.c -endif - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE) -else - LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \ - LIBRARY := jli, \ - OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \ - SRC := $(BUILD_LIBJLI_SRC_DIRS), \ - INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ - LANG := C, \ - OPTIMIZATION := HIGH, \ - CFLAGS := $(LIBJLI_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjli/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_macosx := -framework Cocoa -framework Security -framework ApplicationServices, \ - LDFLAGS_SUFFIX_solaris := $(LIBZ) $(LIBDL) -lc, \ - LDFLAGS_SUFFIX_linux := $(LIBZ) $(LIBDL) -lc -lpthread, \ - LDFLAGS_SUFFIX_macosx := $(LIBZ), \ - LDFLAGS_SUFFIX_windows := \ - -export:JLI_Launch \ - -export:JLI_ManifestIterate \ - -export:JLI_SetTraceLauncher \ - -export:JLI_ReportErrorMessage \ - -export:JLI_ReportErrorMessageSys \ - -export:JLI_ReportMessage \ - -export:JLI_ReportExceptionDescription \ - -export:JLI_MemAlloc \ - -export:JLI_CmdToArgs \ - -export:JLI_GetStdArgc \ - -export:JLI_GetStdArgs \ - advapi32.lib \ - comctl32.lib \ - user32.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jli.dll" \ - -D "JDK_INTERNAL_NAME=jli" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjli, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -BUILD_LIBRARIES += $(BUILD_LIBJLI) - -# On windows, the static library has the same suffix as the import library created by -# with the shared library, so the static library is given a different name. No harm -# in doing it for all platform to reduce complexity. -ifeq ($(OPENJDK_TARGET_OS), windows) - $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ - STATIC_LIBRARY := jli_static, \ - OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ - SRC := $(BUILD_LIBJLI_SRC_DIRS), \ - INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ - LANG := C, \ - OPTIMIZATION := HIGH, \ - CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \ - ARFLAGS := $(ARFLAGS), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjli_static, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBJLI_STATIC) - -else ifeq ($(OPENJDK_TARGET_OS), macosx) - # - # On macosx they do partial (incremental) linking of libjli_static.a - # code it here...rather than add support to NativeCompilation - # as this is first time I see it - $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ - LIBRARY := jli_static, \ - OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ - SRC := $(BUILD_LIBJLI_SRC_DIRS), \ - INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ - LANG := C, \ - OPTIMIZATION := HIGH, \ - CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \ - LDFLAGS := -nostdlib -r, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjli_static, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(JDK_OUTPUTDIR)/objs/libjli_static.a: $(BUILD_LIBJLI_STATIC) - $(call install-file) - - BUILD_LIBRARIES += $(JDK_OUTPUTDIR)/objs/libjli_static.a -endif - -########################################################################################## - -ifndef OPENJDK - ifeq ($(ENABLE_JFR), true) - - $(eval $(call SetupNativeCompilation,BUILD_LIBJFR, \ - LIBRARY := jfr, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/closed/share/native/oracle/jfr, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/closed/share/javavm/export, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjfr/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jfr.dll" \ - -D "JDK_INTERNAL_NAME=jfr" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjfr, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBJFR) - -endif -endif - -########################################################################################## - -ifndef OPENJDK - - BUILD_LIBKCMS_EXCLUDE_FILES := - ifeq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBKCMS_EXCLUDE_FILES += ukcpmgr.c unixmem.c - else - BUILD_LIBKCMS_EXCLUDE_FILES += cmmdll.c registry.c spxffile.c sysinfo.c winmem.c wkcpmgr.c - endif - - BUILD_LIBKCMS_FLAGS := $(CFLAGS_JDKLIB) - - ifeq ($(OPENJDK_TARGET_OS), solaris) - # This particular library uses a feature called PIC_CODE_SMALL (on solaris) - # implement it like this...since it's only used here - BUILD_LIBKCMS_FLAGS := $(patsubst -KPIC, -Kpic, $(BUILD_LIBKCMS_FLAGS)) - else ifeq ($(OPENJDK_TARGET_CPU_ARCH), ppc) - BUILD_LIBKCMS_FLAGS := $(patsubst -fPIC, -fpic, $(BUILD_LIBKCMS_FLAGS)) - endif - - $(eval $(call SetupNativeCompilation,BUILD_LIBKCMS, \ - LIBRARY := kcms, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms, \ - LANG := C, \ - EXCLUDE_FILES := $(BUILD_LIBKCMS_EXCLUDE_FILES), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(BUILD_LIBKCMS_FLAGS) \ - -DJAVACMM -DFUT_CALC_EX -DNO_FUT_GCONST, \ - CFLAGS_linux := -Wno-missing-field-initializers, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libkcms/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := -lc -lpthread, \ - LDFLAGS_SUFFIX_solaris := -lc, \ - LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib version.lib, \ - LDFLAGS_SUFFIX_posix := -lm -ljava -ljvm, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms/cmm.rc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms/cmm.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=kcms.dll" \ - -D "JDK_INTERNAL_NAME=kcms" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libkcms, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBKCMS): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBKCMS) - -endif - -########################################################################################## - -ifndef OPENJDK - ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - - ifeq ($(shell if test "$(OS_VERSION_MAJOR)" -eq 5 -a "$(OS_VERSION_MINOR)" -le 10; then $(ECHO) ok; fi), ok) - - SUNWJDGA_MAPFILE := - ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) - SUNWJDGA_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjdga/mapfile-vers - endif - - $(eval $(call SetupNativeCompilation,BUILD_LIBSUNWJDGA, \ - LIBRARY := sunwjdga, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/solaris/native/sun/jdga, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/javavm/export \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/javavm/export \ - -I$(OPENWIN_HOME)/include, \ - MAPFILE := $(SUNWJDGA_MAPFILE), \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -ldga -lX11 $(LIBDL) -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunwjdga, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBSUNWJDGA) - - endif - endif - endif -endif - -########################################################################################## - -ifeq ($(BUILD_HEADLESS), true) - ifneq ($(OPENJDK_TARGET_OS), windows) - - LIBAWT_HEADLESS_DIRS := $(JDK_TOPDIR)/src/share/native/sun/font \ - $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/solaris/native/sun/font \ - $(JDK_TOPDIR)/src/solaris/native/sun/awt \ - $(JDK_TOPDIR)/src/solaris/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/solaris/native/sun/java2d/x11 - - ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBAWT_HEADLESS_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/font - endif - - LIBAWT_HEADLESS_CFLAGS := -DHEADLESS=true \ - -DX11_PATH=\"$(X11_PATH)\" -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ - $(CUPS_CFLAGS) \ - $(X_CFLAGS) \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga \ - $(foreach dir, $(LIBAWT_HEADLESS_DIRS), -I$(dir)) - - ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBAWT_HEADLESS_CFLAGS += \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks - endif - - LIBAWT_HEADLESS_FILES := \ - awt_Font.c \ - HeadlessToolkit.c \ - fontpath.c \ - VDrawingArea.c \ - X11Color.c \ - X11Renderer.c \ - X11PMBlitLoops.c \ - X11SurfaceData.c \ - X11FontScaler_md.c \ - X11TextRenderer_md.c \ - OGLBlitLoops.c \ - OGLBufImgOps.c \ - OGLContext.c \ - OGLFuncs.c \ - OGLMaskBlit.c \ - OGLMaskFill.c \ - OGLPaints.c \ - OGLRenderQueue.c \ - OGLRenderer.c \ - OGLSurfaceData.c \ - OGLTextRenderer.c \ - OGLVertexCache.c \ - GLXGraphicsConfig.c \ - GLXSurfaceData.c \ - AccelGlyphCache.c \ - CUPSfuncs.c - - ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBAWT_HEADLESS_FILES += \ - AWTFont.m \ - AWTStrike.m \ - CCharToGlyphMapper.m \ - CGGlyphImages.m \ - CGGlyphOutlines.m \ - CoreTextSupport.m - endif - - LIBAWT_HEADLESS_REORDER := - ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - LIBAWT_HEADLESS_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libawt_headless/reorder-$(OPENJDK_TARGET_CPU) - endif - endif - - $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \ - LIBRARY := awt_headless, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBAWT_HEADLESS_DIRS), \ - INCLUDE_FILES := $(LIBAWT_HEADLESS_FILES), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_HEADLESS_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libawt_headless/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..) \ - -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ - LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN)., \ - REORDER := $(LIBAWT_HEADLESS_REORDER), \ - LDFLAGS_SUFFIX_linux := -ljvm -lawt -lm $(LIBDL) -ljava, \ - LDFLAGS_SUFFIX_solaris := $(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc, \ - LDFLAGS_SUFFIX_macosx := -ljvm $(LIBCXX) -lawt $(LIBDL) -ljava \ - -framework Accelerate \ - -framework ApplicationServices \ - -framework Cocoa \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -framework JavaRuntimeSupport, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_headless, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT) - - BUILD_LIBRARIES += $(BUILD_LIBAWT_HEADLESS) - - endif -endif - -########################################################################################## - -ifndef BUILD_HEADLESS_ONLY - LIBSPLASHSCREEN_DIRS := \ - $(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg \ - $(JDK_TOPDIR)/src/share/native/sun/awt/libpng \ - $(JDK_TOPDIR)/src/share/native/sun/awt/splashscreen - - ifeq ($(USE_EXTERNAL_LIBGIF), true) - GIFLIB_LDFLAGS := -lgif - else - LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/sun/awt/giflib - GIFLIB_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/awt/giflib - endif - - ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/splashscreen - else - LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen - endif - - LIBSPLASHSCREEN_CFLAGS := -DSPLASHSCREEN -DPNG_NO_MMX_CODE \ - $(foreach dir, $(LIBSPLASHSCREEN_DIRS), -I$(dir)) - - ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBSPLASHSCREEN_CFLAGS := -I$(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen \ - $(LIBSPLASHSCREEN_CFLAGS) \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks - LIBSPLASHSCREEN_CFLAGS += -DWITH_MACOSX - LIBSPLASHSCREEN_CFLAGS += -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp - - LIBSPLASHSCREEN_java_awt_SplashScreen.c_CFLAGS := -x objective-c -O0 - LIBSPLASHSCREEN_splashscreen_gfx_impl.c_CFLAGS := -x objective-c -O0 - LIBSPLASHSCREEN_splashscreen_gif.c_CFLAGS := -x objective-c -O0 - LIBSPLASHSCREEN_splashscreen_impl.c_CFLAGS := -x objective-c -O0 - LIBSPLASHSCREEN_splashscreen_jpeg.c_CFLAGS := -x objective-c -O0 - LIBSPLASHSCREEN_splashscreen_png.c_CFLAGS := -x objective-c -O0 - LIBSPLASHSCREEN_splashscreen_sys.m_CFLAGS := -O0 - - else ifneq ($(OPENJDK_TARGET_OS), windows) - LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 -I$(OPENWIN_HOME)/include -I$(OPENWIN_HOME)/include/X11/extensions - else - LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32 - endif - - LIBSPLASHSCREEN_LDFLAGS_SUFFIX := - - ifneq ($(USE_EXTERNAL_LIBZ), true) - LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 - LIBSPLASHSCREEN_CFLAGS += $(ZLIB_CPPFLAGS) - endif - - ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(LIBM) -lpthread -liconv -losxapp \ - -framework ApplicationServices \ - -framework Foundation \ - -framework Cocoa \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation - else ifneq ($(OPENJDK_TARGET_OS), windows) - LIBSPLASHSCREEN_LDFLAGS_SUFFIX += -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -lX11 -lXext $(LIBM) -lpthread - else # OPENJDK_TARGET_OS - LIBSPLASHSCREEN_LDFLAGS_SUFFIX += kernel32.lib user32.lib gdi32.lib delayimp.lib -DELAYLOAD:user32.dll - endif # OPENJDK_TARGET_OS - - $(eval $(call SetupNativeCompilation,LIBSPLASHSCREEN, \ - LIBRARY := splashscreen, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBSPLASHSCREEN_DIRS), \ - EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(LIBSPLASHSCREEN_CFLAGS) $(CFLAGS_JDKLIB) $(GIFLIB_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libsplashscreen/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(LIBSPLASHSCREEN_LDFLAGS_SUFFIX) $(LIBZ) $(GIFLIB_LDFLAGS), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=splashscreen.dll" \ - -D "JDK_INTERNAL_NAME=splashscreen" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsplashscreen, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(LIBSPLASHSCREEN) - - ifeq ($(OPENJDK_TARGET_OS), macosx) - $(LIBSPLASHSCREEN): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX) - endif - -endif - -########################################################################################## - -ifndef OPENJDK - - LIBDCPR_SRC_DIRS := \ - $(JDK_TOPDIR)/src/closed/share/native/sun/dc/doe \ - $(JDK_TOPDIR)/src/closed/share/native/sun/dc/path \ - $(JDK_TOPDIR)/src/closed/share/native/sun/dc/pr \ - $(JDK_TOPDIR)/src/closed/share/native/sun/dc/util - - LIBDCPR_CFLAGS := $(foreach dir, $(LIBDCPR_SRC_DIRS), -I$(dir)) \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe - - $(eval $(call SetupNativeCompilation,BUILD_LIBDCPR, \ - LIBRARY := dcpr, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBDCPR_SRC_DIRS), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBDCPR_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libdcpr/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(LIBM) $(LDFLAGS_JDKLIB_SUFFIX), \ - LDFLAGS_SUFFIX_posix := -lm, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=dcpr.dll" \ - -D "JDK_INTERNAL_NAME=dcpr" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libdcpr, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBDCPR): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBDCPR) - -endif - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PCSC, \ - LIBRARY := j2pcsc, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/security/smartcardio \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/smartcardio, \ - LANG := C, \ - CFLAGS_posix := -D__sun_jdk, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/sun/security/smartcardio \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/smartcardio \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/smartcardio/MUSCLE, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2pcsc/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_posix := $(LIBDL), \ - LDFLAGS_SUFFIX_windows := winscard.lib, \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=j2pcsc.dll" \ - -D "JDK_INTERNAL_NAME=j2pcsc" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2pcsc, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -BUILD_LIBRARIES += $(BUILD_LIBJ2PCSC) - -########################################################################################## - -ifneq ($(OPENJDK_TARGET_OS), windows) - $(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS, \ - LIBRARY := j2gss, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/security/jgss/wrapper \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/jgss/wrapper, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/sun/security/jgss/wrapper \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/jgss/wrapper, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2gss/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2gss, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBJ2GSS) -endif - -########################################################################################## - -ifneq ($(BUILD_CRYPTO), no) - BUILD_LIBKRB5_NAME := - ifeq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBKRB5_NAME := w2k_lsa_auth - BUILD_LIBKRB5_SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5 - BUILD_LIBKRB5_LIBS := advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \ - gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \ - ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib - else ifeq ($(OPENJDK_TARGET_OS), macosx) - BUILD_LIBKRB5_NAME := osxkrb5 - BUILD_LIBKRB5_SRC := $(JDK_TOPDIR)/src/share/native/sun/security/krb5 - BUILD_LIBKRB5_LIBS := -framework Kerberos - endif - - ifneq ($(BUILD_LIBKRB5_NAME), ) - $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5, \ - LIBRARY := $(BUILD_LIBKRB5_NAME), \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBKRB5_SRC), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/sun/security/krb5 \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(BUILD_LIBKRB5_LIBS), \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=$(BUILD_LIBKRB5_NAME).dll" \ - -D "JDK_INTERNAL_NAME=$(BUILD_LIBKRB5_NAME)" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libkrb5, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBKRB5) - endif -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), windows) - - $(eval $(call SetupNativeCompilation,BUILD_LIBSUNMSCAPI, \ - LIBRARY := sunmscapi, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := Crypt32.Lib advapi32.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=sunmscapi.dll" \ - -D "JDK_INTERNAL_NAME=sunmscapi" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunmscapi, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBSUNMSCAPI) -endif - -########################################################################################## - -$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \ - LIBRARY := j2pkcs11, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/security/pkcs11 \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11 \ - $(JDK_TOPDIR)/src/share/native/sun/security/pkcs11/wrapper \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11/wrapper, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/share/native/sun/security/pkcs11 \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11 \ - -I$(JDK_TOPDIR)/src/share/native/sun/security/pkcs11/wrapper \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11/wrapper, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2pkcs11/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_posix := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=j2pkcs11.dll" \ - -D "JDK_INTERNAL_NAME=j2pkcs11" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2pkcs11, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -BUILD_LIBRARIES += $(BUILD_LIBJ2PKCS11) - -########################################################################################## - -ifeq ($(ENABLE_INTREE_EC), yes) - - BUILD_LIBSUNEC_FLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/security/ec \ - -I$(JDK_TOPDIR)/src/share/native/sun/security/ec/impl - - # - # On sol-sparc...all libraries are compiled with -xregs=no%appl - # (set in CFLAGS_REQUIRED_sparc) - # - # except!!! libsunec.so - # - ECC_JNI_SOLSPARC_FILTER := - ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) - ECC_JNI_SOLSPARC_FILTER := -xregs=no%appl - endif - - $(eval $(call SetupNativeCompilation,BUILD_LIBSUNEC, \ - LIBRARY := sunec, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/share/native/sun/security/ec \ - $(JDK_TOPDIR)/src/share/native/sun/security/ec/impl, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(filter-out $(ECC_JNI_SOLSPARC_FILTER), $(CFLAGS_JDKLIB)) \ - $(BUILD_LIBSUNEC_FLAGS) \ - -DMP_API_COMPATIBLE -DNSS_ECC_MORE_THAN_SUITE_B, \ - CXXFLAGS := $(filter-out $(ECC_JNI_SOLSPARC_FILTER), $(CXXFLAGS_JDKLIB)) \ - $(BUILD_LIBSUNEC_FLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libsunec/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \ - LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(LIBCXX), \ - LDFLAGS_SUFFIX_linux := -lc, \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=sunec.dll" \ - -D "JDK_INTERNAL_NAME=sunec" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunec, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBSUNEC) -endif - -########################################################################################## - -LIBJSOUND_SRC_DIRS := \ - $(JDK_TOPDIR)/src/share/native/com/sun/media/sound \ - $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/com/sun/media/sound - -LIBJSOUND_SRC_FILES := Utilities.c Platform.c - -LIBJSOUND_LANG := C -LIBJSOUND_CFLAGS := $(foreach dir, $(LIBJSOUND_SRC_DIRS), -I$(dir)) - -EXTRA_SOUND_JNI_LIBS := - -LIBJSOUND_MIDIFILES := \ - MidiInDevice.c \ - MidiInDeviceProvider.c \ - MidiOutDevice.c \ - MidiOutDeviceProvider.c \ - PlatformMidi.c - -# files needed for ports -LIBJSOUND_PORTFILES := \ - PortMixerProvider.c \ - PortMixer.c - -# files needed for direct audio -LIBJSOUND_DAUDIOFILES := \ - DirectAudioDeviceProvider.c \ - DirectAudioDevice.c - -ifeq ($(OPENJDK_TARGET_OS), windows) - EXTRA_SOUND_JNI_LIBS += jsoundds - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS \ - -DUSE_PLATFORM_MIDI_OUT=TRUE \ - -DUSE_PLATFORM_MIDI_IN=TRUE \ - -DUSE_PORTS=TRUE - LIBJSOUND_SRC_FILES += \ - PLATFORM_API_WinOS_MidiIn.cpp \ - PLATFORM_API_WinOS_MidiOut.c \ - PLATFORM_API_WinOS_Util.c \ - PLATFORM_API_WinOS_Ports.c - LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) -endif # OPENJDK_TARGET_OS windows - -ifeq ($(OPENJDK_TARGET_OS), linux) - EXTRA_SOUND_JNI_LIBS += jsoundalsa - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_LINUX -endif # OPENJDK_TARGET_OS linux - -ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBJSOUND_LANG := C++ - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX \ - -DUSE_PORTS=TRUE \ - -DUSE_DAUDIO=TRUE \ - -DUSE_PLATFORM_MIDI_OUT=TRUE \ - -DUSE_PLATFORM_MIDI_IN=TRUE - LIBJSOUND_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/com/sun/media/sound - LIBJSOUND_SRC_FILES += \ - PLATFORM_API_MacOSX_Utils.cpp \ - PLATFORM_API_MacOSX_PCM.cpp \ - PLATFORM_API_MacOSX_Ports.cpp \ - PLATFORM_API_MacOSX_MidiIn.c \ - PLATFORM_API_MacOSX_MidiOut.c \ - PLATFORM_API_MacOSX_MidiUtils.c - LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES) -endif # OPENJDK_TARGET_OS macosx - -ifeq ($(OPENJDK_TARGET_OS), solaris) - LIBJSOUND_CFLAGS += -DX_PLATFORM=X_SOLARIS \ - -DUSE_PORTS=TRUE \ - -DUSE_DAUDIO=TRUE - LIBJSOUND_SRC_FILES += \ - PLATFORM_API_SolarisOS_Utils.c \ - PLATFORM_API_SolarisOS_Ports.c \ - PLATFORM_API_SolarisOS_PCM.c - LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) - LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES) -endif # OPENJDK_TARGET_OS solaris - - -ifeq ($(JVM_VARIANT_ZERO), true) - LIBJSOUND_CFLAGS += -DX_ARCH=X_ZERO -else - ifeq ($(OPENJDK_TARGET_CPU), x86) - LIBJSOUND_CFLAGS += -DX_ARCH=X_I586 - endif - - ifeq ($(OPENJDK_TARGET_CPU), sparc) - LIBJSOUND_CFLAGS += -DX_ARCH=X_SPARC - endif - - ifeq ($(OPENJDK_TARGET_CPU), sparcv9) - LIBJSOUND_CFLAGS += -DX_ARCH=X_SPARCV9 - endif - - ifeq ($(OPENJDK_TARGET_CPU), x86_64) - LIBJSOUND_CFLAGS += -DX_ARCH=X_AMD64 - endif - - ifeq ($(OPENJDK_TARGET_CPU), arm) - LIBJSOUND_CFLAGS += -DX_ARCH=X_ARM - endif - - ifeq ($(OPENJDK_TARGET_CPU), ppc) - LIBJSOUND_CFLAGS += -DX_ARCH=X_PPC - endif -endif - -LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"' - -$(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \ - LIBRARY := jsound, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJSOUND_SRC_DIRS), \ - INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \ - LANG := $(LIBJSOUND_LANG), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBJSOUND_CFLAGS), \ - CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBJSOUND_CFLAGS), \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjsound/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_macosx := -framework CoreAudio -framework CoreFoundation \ - -framework CoreServices -framework AudioUnit $(LIBCXX) \ - -framework CoreMIDI -framework AudioToolbox, \ - LDFLAGS_windows := $(WIN_JAVA_LIB) advapi32.lib winmm.lib, \ - LDFLAGS_SUFFIX_posix := -ljava -ljvm, \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jsound.dll" \ - -D "JDK_INTERNAL_NAME=jsound" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsound, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - -$(BUILD_LIBJSOUND): $(BUILD_LIBJAVA) - -BUILD_LIBRARIES += $(BUILD_LIBJSOUND) - -########################################################################################## - -ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), ) - - $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDALSA, \ - LIBRARY := jsoundalsa, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJSOUND_SRC_DIRS), \ - INCLUDE_FILES := Utilities.c $(LIBJSOUND_MIDIFILES) $(LIBJSOUND_PORTFILES) \ - $(LIBJSOUND_DAUDIOFILES) \ - PLATFORM_API_LinuxOS_ALSA_CommonUtils.c \ - PLATFORM_API_LinuxOS_ALSA_PCM.c \ - PLATFORM_API_LinuxOS_ALSA_PCMUtils.c \ - PLATFORM_API_LinuxOS_ALSA_MidiIn.c \ - PLATFORM_API_LinuxOS_ALSA_MidiOut.c \ - PLATFORM_API_LinuxOS_ALSA_MidiUtils.c \ - PLATFORM_API_LinuxOS_ALSA_Ports.c, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(ALSA_CFLAGS) \ - $(LIBJSOUND_CFLAGS) \ - -DUSE_DAUDIO=TRUE \ - -DUSE_PORTS=TRUE \ - -DUSE_PLATFORM_MIDI_OUT=TRUE \ - -DUSE_PLATFORM_MIDI_IN=TRUE, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjsoundalsa/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(ALSA_LIBS) -ljava -ljvm, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsoundalsa, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBJSOUNDALSA): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBJSOUNDALSA) - -endif - -########################################################################################## - -ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), ) - - $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS, \ - LIBRARY := jsoundds, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJSOUND_SRC_DIRS), \ - INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ - PLATFORM_API_WinOS_DirectSound.cpp, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBJSOUND_CFLAGS) \ - -DUSE_DAUDIO=TRUE, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib, \ - VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jsoundds.dll" \ - -D "JDK_INTERNAL_NAME=jsoundds" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsoundds, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBJSOUNDDS): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBJSOUNDDS) - -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), solaris) - ifndef OPENJDK - - $(eval $(call SetupNativeCompilation,BUILD_LIBJ2UCRYPTO, \ - LIBRARY := j2ucrypto, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/closed/solaris/native/com/oracle/security/ucrypto, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/closed/solaris/native/com/oracle/security/ucrypto, \ - MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2ucrypto/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB), \ - LDFLAGS_SUFFIX := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2ucrypto, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBJ2UCRYPTO) - - endif -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), macosx) - - $(eval $(call SetupNativeCompilation,BUILD_LIBAPPLESCRIPTENGINE, \ - LIBRARY := AppleScriptEngine, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/macosx/native/apple/applescript, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/macosx/native/apple/applescript \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := -framework Cocoa \ - -framework Carbon \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - $(LDFLAGS_JDKLIB_SUFFIX), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libAppleScriptEngine, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBAPPLESCRIPTENGINE): $(BUILD_LIBJAVA) - - BUILD_LIBRARIES += $(BUILD_LIBAPPLESCRIPTENGINE) - -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), macosx) - - $(eval $(call SetupNativeCompilation,BUILD_LIBOSXAPP, \ - LIBRARY := osxapp, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/macosx/native/sun/osxapp, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ - -I$(JDK_OUTPUTDIR)/gensrc/sun/osxapp \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_macosx := \ - -framework Accelerate \ - -framework ApplicationServices \ - -framework AudioToolbox \ - -framework Carbon \ - -framework Cocoa \ - -framework Security \ - -framework ExceptionHandling \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -framework JavaRuntimeSupport \ - -framework OpenGL \ - -framework IOSurface \ - -framework QuartzCore, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libosxapp, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBOSXAPP) - -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), macosx) - - LIBOSX_DIRS := \ - $(JDK_TOPDIR)/src/macosx/native/com/apple/concurrent \ - $(JDK_TOPDIR)/src/macosx/native/java/util \ - $(JDK_TOPDIR)/src/macosx/native/com/apple/eio \ - $(JDK_TOPDIR)/src/macosx/native/apple/security \ - $(JDK_TOPDIR)/src/macosx/native/apple/launcher - - $(eval $(call SetupNativeCompilation,BUILD_LIBOSX, \ - LIBRARY := osx, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBOSX_DIRS), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(foreach dir, $(LIBOSX_DIRS), -I$(dir)) \ - -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_macosx := \ - -losxapp \ - -framework Cocoa \ - -framework ApplicationServices \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -framework JavaRuntimeSupport \ - -framework Security \ - -framework SystemConfiguration \ - $(LDFLAGS_JDKLIB_SUFFIX), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libosx, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBOSX) - - $(BUILD_LIBOSX): $(BUILD_LIBOSXAPP) - - $(BUILD_LIBOSX): $(BUILD_LIBJAVA) - -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), macosx) - - LIBAWT_LWAWT_FILES := \ - awt.m \ - ApplicationDelegate.m \ - CFRetainedResource.m \ - CGLGraphicsConfig.m \ - CGLSurfaceData.m \ - CGLLayer.m \ - CGraphicsConfig.m \ - CGraphicsDevice.m \ - CGraphicsEnv.m \ - CCharToGlyphMapper.m \ - CSystemColors.m \ - AWTFont.m \ - CGGlyphOutlines.m \ - CGGlyphImages.m \ - CoreTextSupport.m \ - AWTStrike.m \ - InitIDs.m \ - AWTEvent.m \ - AWTView.m \ - AWTWindow.m \ - AWTSurfaceLayers.m \ - CCursorManager.m \ - CClipboard.m \ - CDataTransferer.m \ - CDragSource.m \ - CDragSourceContextPeer.m \ - CDropTarget.m \ - CDropTargetContextPeer.m \ - CInputMethod.m \ - CDesktopPeer.m \ - OSVersion.m \ - DnDUtilities.m \ - CFileDialog.m \ - CImage.m \ - CMenu.m \ - CMenuBar.m \ - CMenuComponent.m \ - CMenuItem.m \ - CPopupMenu.m \ - CRobot.m \ - CTrayIcon.m \ - CWrapper.m \ - JavaAccessibilityAction.m \ - JavaAccessibilityUtilities.m \ - JavaComponentAccessibility.m \ - JavaTextAccessibility.m \ - LWCToolkit.m \ - GeomUtilities.m \ - CPrinterJob.m \ - PrintModel.m \ - PrinterSurfaceData.m \ - PrinterView.m \ - QuartzSurfaceData.m \ - QuartzRenderer.m \ - CTextPipe.m \ - ImageSurfaceData.m \ - awt_DrawingSurface.m \ - \ - OGLBlitLoops.c \ - OGLBufImgOps.c \ - OGLContext.c \ - OGLFuncs.c \ - OGLMaskBlit.c \ - OGLMaskFill.c \ - OGLPaints.c \ - OGLRenderQueue.c \ - OGLRenderer.c \ - OGLSurfaceData.c \ - OGLTextRenderer.c \ - OGLVertexCache.c \ - AccelGlyphCache.c \ - CUPSfuncs.c - - - LIBAWT_LWAWT_DIRS := \ - $(JDK_TOPDIR)/src/macosx/native/sun/awt \ - $(JDK_TOPDIR)/src/macosx/native/sun/font \ - $(JDK_TOPDIR)/src/macosx/native/sun/java2d/opengl \ - $(JDK_TOPDIR)/src/solaris/native/sun/awt \ - $(JDK_TOPDIR)/src/share/native/sun/font \ - $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ - - $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_LWAWT, \ - LIBRARY := awt_lwawt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBAWT_LWAWT_DIRS), \ - LANG := C, \ - INCLUDE_FILES := $(LIBAWT_LWAWT_FILES), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(X_CFLAGS) \ - $(X_LIBS) \ - $(foreach dir, $(LIBAWT_LWAWT_DIRS), -I$(dir)) \ - -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/solaris/native/sun/java2d \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ - -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ - -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_macosx := -lawt -lmlib_image -losxapp -ljvm $(LIBM) \ - -framework Accelerate \ - -framework ApplicationServices \ - -framework AudioToolbox \ - -framework Carbon \ - -framework Cocoa \ - -framework Security \ - -framework ExceptionHandling \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -framework JavaRuntimeSupport \ - -framework OpenGL \ - -framework QuartzCore -ljava, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_lwawt, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBAWT_LWAWT) - - $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBAWT) - - $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBMLIB_IMAGE) - - $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBOSXAPP) - - $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBJAVA) - -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), macosx) - - $(eval $(call SetupNativeCompilation,BUILD_LIBOSXUI, \ - LIBRARY := osxui, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/macosx/native/com/apple/laf, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(JDK_TOPDIR)/src/macosx/native/com/apple/laf \ - -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ - -I$(JDK_TOPDIR)/src/macosx/native/sun/awt \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - -Xlinker -rpath -Xlinker @loader_path, \ - LDFLAGS_SUFFIX_macosx := -lawt -losxapp -lawt_lwawt \ - -framework Cocoa \ - -framework Carbon \ - -framework ApplicationServices \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -framework JavaRuntimeSupport \ - -ljava -ljvm, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libosxui, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - BUILD_LIBRARIES += $(BUILD_LIBOSXUI) - - $(BUILD_LIBOSXUI): $(BUILD_LIBAWT) - - $(BUILD_LIBOSXUI): $(BUILD_LIBOSXAPP) - - $(BUILD_LIBOSXUI): $(BUILD_LIBAWT_LWAWT) - - #$(BUILD_LIBOSXUI): $(BUILD_LIBJAVA) - -endif - -########################################################################################## - -ifeq ($(OPENJDK_TARGET_OS), macosx) - - # Ugly hack to mimic behaviour in old build where this is built as an xcode project. - SET_SHARED_LIBRARY_NAME = -Xlinker -install_name -Xlinker /usr/local/lib/libJObjC.dylib - - $(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC32, \ - LIBRARY := JObjC, \ - OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \ - SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \ - $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := -fpascal-strings \ - -fobjc-gc \ - -gdwarf-2 \ - $(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -m32, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - -m32, \ - LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -lffi, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC64, \ - LIBRARY := JObjC, \ - OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \ - SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \ - $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := -fpascal-strings \ - -fobjc-gc \ - -gdwarf-2 \ - $(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - , \ - LDFLAGS := -fpascal-strings \ - -fobjc-gc \ - -gdwarf-2 \ - $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \ - -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ - -framework JavaNativeFoundation \ - -lffi, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX): $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64) - $(LIPO) -create -output $@ $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64) - - BUILD_LIBRARIES += $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX) - -endif - -########################################################################################## - -ifndef OPENJDK - ifeq ($(OPENJDK_TARGET_OS), windows) - - ACCESSBRIDGE_SRCDIR := $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge - - define SetupAccessBridge - # Parameter 1 Suffix - # Parameter 2 Machine - # Parameter 3 ACCESSBRIDGE_ARCH_ suffix - - $(call SetupNativeCompilation,BUILD_JAWTACCESSBRIDGE$1, \ - LIBRARY = JAWTAccessBridge$1, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(ACCESSBRIDGE_SRCDIR), \ - INCLUDE_FILES := JAWTAccessBridge.cpp, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -DACCESSBRIDGE_ARCH_$3, \ - LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ - winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib \ - ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ - -subsystem:windows -machine:$2 \ - -def:$(ACCESSBRIDGE_SRCDIR)/JAWTAccessBridge.DEF, \ - VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ - RC_FLAGS := $(RC_FLAGS), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawtaccessbridge$1, \ - DEBUG_SYMBOLS := true) - - $$(BUILD_JAWTACCESSBRIDGE$1): $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX) - - $(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1, \ - LIBRARY = JavaAccessBridge$1, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(ACCESSBRIDGE_SRCDIR), \ - INCLUDE_FILES := AccessBridgeATInstance.cpp AccessBridgeDebug.cpp \ - AccessBridgeJavaEntryPoints.cpp \ - AccessBridgeMessages.cpp JavaAccessBridge.cpp, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -DACCESSBRIDGE_ARCH_$3, \ - LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ - winspool.lib comdlg32.lib advapi32.lib shell32.lib \ - ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ - -subsystem:windows -machine:$2 \ - -def:$(ACCESSBRIDGE_SRCDIR)/JavaAccessBridge.DEF, \ - VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ - RC_FLAGS := $(RC_FLAGS), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjavaaccessbridge$1, \ - DEBUG_SYMBOLS := true) - - $(call SetupNativeCompilation,BUILD_WINDOWSACCESSBRIDGE$1, \ - LIBRARY = WindowsAccessBridge$1, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(ACCESSBRIDGE_SRCDIR), \ - INCLUDE_FILES := AccessBridgeJavaVMInstance.cpp AccessBridgeMessageQueue.cpp \ - AccessBridgeMessages.cpp AccessBridgeWindowsEntryPoints.cpp \ - WinAccessBridge.cpp AccessBridgeDebug.cpp \ - AccessBridgeEventHandler.cpp, \ - LANG := C++, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(filter-out -MD, $(CFLAGS_JDKLIB)) -MT \ - -DACCESSBRIDGE_ARCH_$3, \ - LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ - winspool.lib comdlg32.lib advapi32.lib shell32.lib \ - ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ - -subsystem:windows -machine:$2 \ - -def:$(ACCESSBRIDGE_SRCDIR)/WinAccessBridge.DEF, \ - VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ - RC_FLAGS := $(RC_FLAGS), \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libwindowsaccessbridge$1, \ - DEBUG_SYMBOLS := true) - - BUILD_LIBRARIES += $$(BUILD_JAWTACCESSBRIDGE$1) $$(BUILD_JAVAACCESSBRIDGE$1) \ - $$(BUILD_WINDOWSACCESSBRIDGE$1) - - endef - - ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) - $(eval $(call SetupAccessBridge,-32,I386,32)) - $(eval $(call SetupAccessBridge,,I386,LEGACY)) - else - $(eval $(call SetupAccessBridge,-64,X64,64)) - endif - endif -endif +include lib/Awt2dLibraries.gmk +include lib/SoundLibraries.gmk ########################################################################################## diff --git a/jdk/makefiles/lib/Awt2dLibraries.gmk b/jdk/makefiles/lib/Awt2dLibraries.gmk new file mode 100644 index 00000000000..12713650758 --- /dev/null +++ b/jdk/makefiles/lib/Awt2dLibraries.gmk @@ -0,0 +1,1529 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# TODO replace with X_FLAGS / X_LIBS +# and add them to configure +# +OPENWIN_LIB := $(OPENWIN_HOME)/lib + +WIN_AWT_LIB := $(JDK_OUTPUTDIR)/objs/libawt/awt.lib + +########################################################################################## + +BUILD_LIBMLIB_SRC := $(JDK_TOPDIR)/src/share/native/sun/awt/medialib +BUILD_LIBMLIB_CFLAGS := -D__USE_J2D_NAMES -D__MEDIALIB_OLD_NAMES \ + -I$(BUILD_LIBMLIB_SRC) \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib + +BUILD_LIBMLIB_LDLIBS := +BUILD_LIBMLIB_IMAGE_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libmlib_image/mapfile-vers + +BUILD_LIBMLIB_CFLAGS += -DMLIB_NO_LIBSUNMATH + +ifeq ($(OPENJDK_TARGET_CPU_BITS), 64) + BUILD_LIBMLIB_CFLAGS += -DMLIB_OS64BIT +endif + +ifneq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBMLIB_LDLIBS += $(LIBM) $(LIBDL) +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE, \ + LIBRARY := mlib_image, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(BUILD_LIBMLIB_SRC), \ + EXCLUDE_FILES := awt_ImagingLib.c mlib_c_ImageBlendTable.c, \ + LANG := C, \ + OPTIMIZATION := HIGHEST, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(BUILD_LIBMLIB_CFLAGS), \ + MAPFILE := $(BUILD_LIBMLIB_IMAGE_MAPFILE), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(BUILD_LIBMLIB_LDLIBS) \ + $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=mlib_image.dll" \ + -D "JDK_INTERNAL_NAME=mlib_image" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libmlib_image, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBMLIB_IMAGE): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBMLIB_IMAGE) + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) + + BUILD_LIBMLIB_IMAGE_V_FILES := \ + mlib_v_ImageLookUp.c \ + mlib_ImageCreate.c \ + mlib_ImageAffine.c \ + mlib_ImageConvMxN.c \ + mlib_ImageConvKernelConvert.c \ + mlib_sys.c \ + mlib_ImageLookUp_64.c \ + mlib_ImageLookUp_Bit.c \ + mlib_ImageColorTrue2Index.c \ + mlib_c_ImageThresh1_U8.c \ + mlib_v_ImageLookUpS16S16Func.c \ + mlib_v_ImageLookUpS16S32Func.c \ + mlib_v_ImageLookUpS16U16Func.c \ + mlib_v_ImageLookUpS16U8Func.c \ + mlib_v_ImageLookUpS32S16Func.c \ + mlib_v_ImageLookUpS32S32Func.c \ + mlib_v_ImageLookUpS32U16Func.c \ + mlib_v_ImageLookUpS32U8Func.c \ + mlib_v_ImageLookUpSIS16S16Func.c \ + mlib_v_ImageLookUpSIS16S32Func.c \ + mlib_v_ImageLookUpSIS16U16Func.c \ + mlib_v_ImageLookUpSIS16U8Func.c \ + mlib_v_ImageLookUpSIS32S16Func.c \ + mlib_v_ImageLookUpSIS32S32Func.c \ + mlib_v_ImageLookUpSIS32U16Func.c \ + mlib_v_ImageLookUpSIS32U8Func.c \ + mlib_v_ImageLookUpSIU16S16Func.c \ + mlib_v_ImageLookUpSIU16S32Func.c \ + mlib_v_ImageLookUpSIU16U16Func.c \ + mlib_v_ImageLookUpSIU16U8Func.c \ + mlib_v_ImageLookUpSIU8S16Func.c \ + mlib_v_ImageLookUpSIU8S32Func.c \ + mlib_v_ImageLookUpSIU8U16Func.c \ + mlib_v_ImageLookUpSIU8U8Func.c \ + mlib_v_ImageLookUpU16S16Func.c \ + mlib_v_ImageLookUpU16S32Func.c \ + mlib_v_ImageLookUpU16U16Func.c \ + mlib_v_ImageLookUpU16U8Func.c \ + mlib_v_ImageLookUpU8S16Func.c \ + mlib_v_ImageLookUpU8S32Func.c \ + mlib_v_ImageLookUpU8U16Func.c \ + mlib_v_ImageLookUpU8U8Func.c \ + mlib_v_ImageAffineIndex_BC.c \ + mlib_v_ImageAffine_BC.c \ + mlib_v_ImageAffine_BC_S16.c \ + mlib_v_ImageAffine_BC_U16.c \ + mlib_v_ImageAffine_BL.c \ + mlib_v_ImageAffine_BL_S16.c \ + mlib_v_ImageAffine_BL_U16.c \ + mlib_v_ImageAffine_NN.c \ + mlib_v_ImageFilters.c \ + mlib_ImageAffineEdge.c \ + mlib_ImageAffine_BC_D64.c \ + mlib_ImageAffine_BC_F32.c \ + mlib_ImageAffine_BC_S32.c \ + mlib_ImageAffine_BL_D64.c \ + mlib_ImageAffine_BL_F32.c \ + mlib_ImageAffine_BL_S32.c \ + mlib_ImageAffine_NN.c \ + mlib_ImageAffine_NN_Bit.c \ + mlib_ImageFilters.c \ + mlib_ImageScanPoly.c \ + mlib_ImageConv_8nw.c \ + mlib_ImageConv_8ext.c \ + mlib_ImageConv_16nw.c \ + mlib_ImageConv_16ext.c \ + mlib_ImageConv_u16nw.c \ + mlib_ImageConv_u16ext.c \ + mlib_ImageConv_32nw.c \ + mlib_ImageConv_F32nw.c \ + mlib_ImageConvMxN_Fp.c \ + mlib_ImageConvMxN_ext.c \ + mlib_ImageConv_D64nw.c \ + mlib_ImageClipping.c \ + mlib_ImageConvCopyEdge_Bit.c \ + mlib_ImageConvClearEdge_Bit.c \ + mlib_ImageConv2x2_f.c \ + mlib_ImageConvClearEdge_Fp.c \ + mlib_v_ImageConvMxN_8.c \ + mlib_v_ImageConvClearEdge.c \ + mlib_v_ImageConvCopyEdge.c \ + mlib_v_ImageConvMxN_8ext.c \ + mlib_v_ImageConvVersion.c \ + mlib_v_ImageConv_8nw.c \ + mlib_ImageConvCopyEdge_Fp.c \ + mlib_v_ImageChannelInsert_1.c \ + mlib_v_ImageChannelExtract_43.c \ + mlib_v_ImageChannelExtract_1.c \ + mlib_ImageCopy_Bit.c \ + mlib_v_ImageCopy_f.c \ + mlib_ImageUtils.c \ + mlib_ImageDivTables.c + + BUILD_LIBMLIB_V_CFLAGS := $(filter-out -DMLIB_NO_LIBSUNMATH, $(BUILD_LIBMLIB_CFLAGS)) + + $(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE_V, \ + LIBRARY := mlib_image_v, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/awt/medialib \ + $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib, \ + LANG := C, \ + INCLUDE_FILES := $(BUILD_LIBMLIB_IMAGE_V_FILES), \ + OPTIMIZATION := HIGHEST, \ + CFLAGS := -xarch=sparcvis \ + $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib/vis_$(OPENJDK_TARGET_CPU_BITS).il \ + $(BUILD_LIBMLIB_V_CFLAGS) \ + $(CFLAGS_JDKLIB), \ + MAPFILE := $(BUILD_LIBMLIB_IMAGE_MAPFILE), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(BUILD_LIBMLIB_LDLIBS) -ljava -ljvm \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libmlib_image_v, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBMLIB_IMAGE_V): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBMLIB_IMAGE_V) + +endif + +########################################################################################## + +LIBAWT_DIRS := \ + $(JDK_TOPDIR)/src/share/native/sun/awt \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ + $(JDK_TOPDIR)/src/share/native/sun/awt/image \ + $(JDK_TOPDIR)/src/share/native/sun/awt/image/gif \ + $(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ + $(JDK_TOPDIR)/src/share/native/sun/awt/medialib \ + $(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + $(JDK_TOPDIR)/src/share/native/sun/awt/utility \ + $(JDK_TOPDIR)/src/share/native/sun/java2d \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ + $(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ + $(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ + $(JDK_TOPDIR)/src/share/native/sun/awt/image \ + $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/share/native/sun/font + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBAWT_DIRS += \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d +else + LIBAWT_DIRS += \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 +endif + +LIBAWT_CFLAGS += -D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \ + $(X_CFLAGS) \ + $(foreach dir, $(LIBAWT_DIRS), -I$(dir)) + +LIBAWT_FILES := \ + gifdecoder.c \ + imageInitIDs.c \ + img_globals.c \ + SurfaceData.c \ + Region.c \ + BufImgSurfaceData.c \ + Disposer.c \ + Trace.c \ + GraphicsPrimitiveMgr.c \ + Blit.c \ + BlitBg.c \ + ScaledBlit.c \ + FillRect.c \ + FillSpans.c \ + FillParallelogram.c \ + DrawParallelogram.c \ + DrawLine.c \ + DrawRect.c \ + DrawPolygons.c \ + DrawPath.c \ + FillPath.c \ + ProcessPath.c \ + MaskBlit.c \ + MaskFill.c \ + TransformHelper.c \ + AlphaMath.c \ + AlphaMacros.c \ + AnyByte.c \ + ByteBinary1Bit.c \ + ByteBinary2Bit.c \ + ByteBinary4Bit.c \ + ByteIndexed.c \ + ByteGray.c \ + Index8Gray.c \ + Index12Gray.c \ + AnyShort.c \ + Ushort555Rgb.c \ + Ushort565Rgb.c \ + Ushort4444Argb.c \ + Ushort555Rgbx.c \ + UshortGray.c \ + UshortIndexed.c \ + Any3Byte.c \ + ThreeByteBgr.c \ + AnyInt.c \ + IntArgb.c \ + IntArgbPre.c \ + IntArgbBm.c \ + IntRgb.c \ + IntBgr.c \ + IntRgbx.c \ + Any4Byte.c \ + FourByteAbgr.c \ + FourByteAbgrPre.c \ + BufferedMaskBlit.c \ + BufferedRenderPipe.c \ + ShapeSpanIterator.c \ + SpanClipRenderer.c \ + awt_ImageRep.c \ + awt_ImagingLib.c \ + awt_Mlib.c \ + awt_parseImage.c \ + DataBufferNative.c \ + dither.c \ + debug_assert.c \ + debug_mem.c \ + debug_trace.c \ + debug_util.c + +ifneq (, $(filter $(OPENJDK_TARGET_OS), solaris linux)) + LIBAWT_FILES += awt_LoadLibrary.c initIDs.c img_colors.c +endif + +ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBAWT_FILES += awt_LoadLibrary.c img_colors.c + LIBAWT_DIRS += $(JDK_TOPDIR)/src/macosx/native/com/apple/resources + LIBAWT_FILES += awt_LoadLibrary.c MacOSXResourceBundle.m + LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks + + LIBAWT_MacOSXResourceBundle.m_CFLAGS := -O0 +endif + +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) + LIBAWT_CFLAGS += -DMLIB_ADD_SUFF + LIBAWT_CFLAGS += -xarch=sparcvis + LIBAWT_CFLAGS += $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib/vis_$(OPENJDK_TARGET_CPU_BITS).il + LIBAWT_CFLAGS += \ + -I$(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib \ + -I$(JDK_TOPDIR)/src/solaris/native/sun/java2d/medialib \ + -I$(JDK_TOPDIR)/src/solaris/native/sun/java2d/loops + + LIBAWT_DIRS += $(JDK_TOPDIR)/src/solaris/native/sun/awt/medialib \ + $(JDK_TOPDIR)/src/solaris/native/sun/java2d/loops + + LIBAWT_FILES += \ + vis_FuncArray.c \ + java2d_Mlib.c \ + mlib_ImageCreate.c \ + mlib_ImageZoom_NN.c \ + mlib_ImageCopy_Bit.c \ + mlib_sys.c \ + mlib_v_ImageClear.c \ + mlib_v_ImageClear_f.c \ + mlib_v_ImageConstXor.c \ + mlib_v_ImageCopy.c \ + mlib_v_ImageCopy_f.c \ + mlib_v_ImageXor.c \ + mlib_v_ImageZoom_NN_f.c \ + vis_Interp.c \ + vis_AlphaMacros.c \ + vis_AlphaMaskBlit.c \ + vis_AlphaMaskFill.c \ + vis_ByteGray.c \ + vis_ByteGray_FromRgb.c \ + vis_ByteGray_Mask.c \ + vis_ByteIndexed.c \ + vis_DrawLine.c \ + vis_FourByteAbgr.c \ + vis_IntArgb.c \ + vis_IntArgbPre.c \ + vis_IntArgbPre_Mask.c \ + vis_IntBgr.c \ + vis_IntRgb.c \ + vis_IntRgbx.c \ + vis_SrcMaskFill.c \ + vis_SrcOverMaskBlit.c \ + vis_SrcOverMaskFill.c \ + vis_FourByteAbgrPre.c \ + vis_GlyphList.c \ + vis_GlyphListXor.c \ + vis_IntArgbBm.c \ + vis_ThreeByteBgr.c \ + vis_UshortGray.c \ + vis_UshortGray_FromRgb.c \ + vis_XorBlit.c \ + mlib_v_ImageCopy_blk.s + + ifeq ($(OPENJDK_TARGET_CPU), sparcv9) + LIBAWT_ASFLAGS = -P -xarch=v9a + else + LIBAWT_ASFLAGS = -P -xarch=v8plusa + endif +else + LIBAWT_FILES += MapAccelFunc.c +endif + +ifneq ($(OPENJDK_TARGET_OS), solaris) + LIBAWT_CFLAGS += -DMLIB_NO_LIBSUNMATH +endif + +LIBAWT_LANG := C + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBAWT_FILES += AccelGlyphCache.c \ + ShaderList.c \ + CmdIDList.cpp \ + Hashtable.cpp \ + GDIHashtable.cpp \ + Devices.cpp \ + ObjectList.cpp \ + GDIBlitLoops.cpp \ + GDIRenderer.cpp \ + GDIWindowSurfaceData.cpp \ + WindowsFlags.cpp \ + WPrinterJob.cpp \ + awt_%.cpp \ + D3DBlitLoops.cpp \ + D3DBufImgOps.cpp \ + D3DContext.cpp \ + D3DGlyphCache.cpp \ + D3DGraphicsDevice.cpp \ + D3DMaskBlit.cpp \ + D3DMaskCache.cpp \ + D3DMaskFill.cpp \ + D3DPipelineManager.cpp \ + D3DPaints.cpp \ + D3DRenderer.cpp \ + D3DRenderQueue.cpp \ + D3DResourceManager.cpp \ + D3DSurfaceData.cpp \ + D3DTextRenderer.cpp \ + D3DVertexCacher.cpp \ + ShellFolder2.cpp \ + ThemeReader.cpp \ + ComCtl32Util.cpp \ + DllUtil.cpp \ + initIDs.cpp \ + MouseInfo.cpp \ + rect.c \ + OGLBlitLoops.c \ + OGLBufImgOps.c \ + OGLContext.c \ + OGLFuncs.c \ + OGLMaskBlit.c \ + OGLMaskFill.c \ + OGLPaints.c \ + OGLRenderQueue.c \ + OGLRenderer.c \ + OGLSurfaceData.c \ + OGLTextRenderer.c \ + OGLVertexCache.c \ + WGLGraphicsConfig.c \ + WGLSurfaceData.c + + LIBAWT_LANG := C++ + LIBAWT_CFLAGS += -EHsc -DUNICODE -D_UNICODE + ifeq ($(OPENJDK_TARGET_CPU_BITS), 64) + LIBAWT_CFLAGS += -DMLIB_OS64BIT + endif + + ifdef OPENJDK + LIBAWT_RC_FLAGS := -i "$(JDK_TOPDIR)/src/windows/resource/icons" + else + LIBAWT_RC_FLAGS := -i "$(JDK_TOPDIR)/src/closed/windows/native/sun/windows" + endif + LIBAWT_VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/native/sun/windows/awt.rc +endif + +ifeq ($(MILESTONE), internal) + LIBAWT_CFLAGS += -DINTERNAL_BUILD +endif + +LIBAWT_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libawt/mapfile-vers +ifeq ($(OPENJDK_TARGET_OS), linux) + LIBAWT_MAPFILE := +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \ + LIBRARY := awt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBAWT_DIRS), \ + INCLUDE_FILES := $(LIBAWT_FILES), \ + LANG := $(LIBAWT_LANG), \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_CFLAGS), \ + ASFLAGS := $(LIBAWT_ASFLAGS), \ + MAPFILE := $(LIBAWT_MAPFILE), \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_solaris := -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ + LDFLAGS_SUFFIX_linux := -ljvm $(LIBM) $(LIBDL) -ljava, \ + LDFLAGS_SUFFIX_solaris := -ljvm $(LIBM) $(LIBDL) -ljava -lc, \ + LDFLAGS_SUFFIX_macosx := -lmlib_image -ljvm $(LIBM) \ + -framework Cocoa \ + -framework OpenGL \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -framework JavaRuntimeSupport \ + -framework ApplicationServices \ + -framework AudioToolbox \ + -ljava, \ + LDFLAGS_SUFFIX_windows := kernel32.lib user32.lib gdi32.lib winspool.lib \ + imm32.lib ole32.lib uuid.lib shell32.lib \ + comdlg32.lib winmm.lib comctl32.lib shlwapi.lib \ + delayimp.lib jvm.lib $(WIN_JAVA_LIB) advapi32.lib \ + -DELAYLOAD:user32.dll -DELAYLOAD:gdi32.dll \ + -DELAYLOAD:shell32.dll -DELAYLOAD:winmm.dll \ + -DELAYLOAD:winspool.drv -DELAYLOAD:imm32.dll \ + -DELAYLOAD:ole32.dll -DELAYLOAD:comdlg32.dll \ + -DELAYLOAD:comctl32.dll -DELAYLOAD:shlwapi.dll, \ + VERSIONINFO_RESOURCE := $(LIBAWT_VERSIONINFO_RESOURCE), \ + RC_FLAGS := $(RC_FLAGS) $(LIBAWT_RC_FLAGS) \ + -D "JDK_FNAME=awt.dll" \ + -D "JDK_INTERNAL_NAME=awt" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBAWT): $(BUILD_LIBJAVA) + +ifeq ($(OPENJDK_TARGET_OS), macosx) + $(BUILD_LIBAWT): $(BUILD_LIBMLIB_IMAGE) +endif + +BUILD_LIBRARIES += $(BUILD_LIBAWT) + +########################################################################################## + +# TODO!! +# Even though this variable as a general name, it is +# only used on macos, in fontpath.c, as prefix for where to find fonts. +# +# It's used for libawt_headless _and_ libawt_xawt +# +X11_PATH := /usr/X11R6 + +ifneq ($(OPENJDK_TARGET_OS), windows) + ifndef BUILD_HEADLESS_ONLY + + LIBAWT_XAWT_DIRS := \ + $(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + $(JDK_TOPDIR)/src/share/native/sun/awt/utility \ + $(JDK_TOPDIR)/src/share/native/sun/font \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/font \ + $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/xawt \ + + LIBAWT_XAWT_CFLAGS := -DXAWT -DXAWT_HACK \ + -DX11_PATH=\"$(X11_PATH)\" -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ + $(CUPS_CFLAGS) \ + $(foreach dir, $(LIBAWT_XAWT_DIRS), -I$(dir)) \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga + + ifeq ($(OPENJDK_TARGET_OS), solaris) + LIBAWT_XAWT_CFLAGS += -DFUNCPROTO=15 + endif + + ifeq ($(OPENJDK_TARGET_OS), linux) + ifndef OPENJDK + include $(JDK_TOPDIR)/make/closed/xawt.gmk + endif + + ifeq ($(DISABLE_XRENDER), true) + LIBAWT_XAWT_CFLAGS += -DDISABLE_XRENDER_BY_DEFAULT=true + endif + endif + + ifeq ($(MILESTONE), internal) + LIBAWT_XAWT_CFLAGS += -DINTERNAL_BUILD + endif + + LIBAWT_XAWT_FILES := \ + XlibWrapper.c \ + XWindow.c \ + XToolkit.c \ + X11Color.c \ + X11SurfaceData.c \ + awt_GraphicsEnv.c \ + awt_InputMethod.c \ + robot_common.c \ + awt_Robot.c \ + list.c \ + multiVis.c \ + initIDs.c \ + awt_util.c \ + awt_Desktop.c \ + awt_UNIXToolkit.c \ + X11FontScaler_md.c \ + X11TextRenderer_md.c \ + fontpath.c \ + awt_Insets.c \ + awt_Event.c \ + X11Renderer.c \ + X11PMBlitLoops.c \ + OGLBlitLoops.c \ + OGLBufImgOps.c \ + OGLContext.c \ + OGLFuncs.c \ + OGLMaskBlit.c \ + OGLMaskFill.c \ + OGLPaints.c \ + OGLRenderQueue.c \ + OGLRenderer.c \ + OGLSurfaceData.c \ + OGLTextRenderer.c \ + OGLVertexCache.c \ + GLXGraphicsConfig.c \ + GLXSurfaceData.c \ + AccelGlyphCache.c \ + awt_Font.c \ + multi_font.c \ + awt_AWTEvent.c \ + awt_DrawingSurface.c \ + jawt.c \ + CUPSfuncs.c \ + debug_assert.c \ + debug_mem.c \ + debug_trace.c \ + debug_util.c \ + awt_Plugin.c \ + gnome_interface.c \ + gtk2_interface.c \ + swing_GTKEngine.c \ + swing_GTKStyle.c \ + rect.c \ + sun_awt_X11_GtkFileDialogPeer.c \ + XRSurfaceData.c \ + XRBackendNative.c + + LIBAWT_XAWT_LDFLAGS_SUFFIX := $(LIBM) -lawt -lXext -lX11 -lXrender $(LIBDL) -lXtst -lXi -ljava -ljvm -lc + + ifeq ($(OPENJDK_TARGET_OS), linux) + # To match old build, add this to LDFLAGS instead of suffix. + LIBAWT_XAWT_LDFLAGS += -lpthread + endif + + ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBAWT_XAWT_LDFLAGS_SUFFIX += -lpthread + endif + + # On macosx, the shared library origin is set twice for this lib. + $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_XAWT, \ + LIBRARY := awt_xawt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBAWT_XAWT_DIRS), \ + INCLUDE_FILES := $(LIBAWT_XAWT_FILES), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_XAWT_CFLAGS) \ + $(X_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libawt_xawt/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(X_LIBS) $(LIBAWT_XAWT_LDFLAGS), \ + LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + LDFLAGS_solaris := -L$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) \ + -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) \ + -R$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) \ + -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) \ + -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(call SET_SHARED_LIBRARY_ORIGIN). \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(call SET_SHARED_LIBRARY_ORIGIN)., \ + LDFLAGS_SUFFIX := $(LIBAWT_XAWT_LDFLAGS_SUFFIX), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=xawt.dll" \ + -D "JDK_INTERNAL_NAME=xawt" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_xawt, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBAWT_XAWT): $(BUILD_LIBJAVA) + + $(BUILD_LIBAWT_XAWT): $(BUILD_LIBAWT) + + BUILD_LIBRARIES += $(BUILD_LIBAWT_XAWT) + + endif +endif + +########################################################################################## + +# TODO: Update awt lib path when awt is converted +$(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \ + LIBRARY := lcms, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms, \ + LANG := C, \ + OPTIMIZATION := HIGHEST, \ + CFLAGS := $(filter-out -xc99=%none, $(CFLAGS_JDKLIB)) \ + $(SHARED_LIBRARY_FLAGS) \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug, \ + CFLAGS_solaris := -xc99=no_lib, \ + CFLAGS_windows := -DCMS_IS_WINDOWS_, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/liblcms/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_solaris := /usr/lib$(OPENJDK_TARGET_CPU_ISADIR)/libm.so.2, \ + LDFLAGS_windows := $(WIN_AWT_LIB) $(WIN_JAVA_LIB), \ + LDFLAGS_SUFFIX_solaris := -lawt -ljava -ljvm -lc, \ + LDFLAGS_SUFFIX_macosx := $(LIBM) -lawt -ljava -ljvm, \ + LDFLAGS_SUFFIX_linux := -lm -lawt -ljava -ljvm, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=lcms.dll" \ + -D "JDK_INTERNAL_NAME=lcms" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/liblcms, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +BUILD_LIBRARIES += $(BUILD_LIBLCMS) + +$(BUILD_LIBLCMS): $(BUILD_LIBAWT) + +########################################################################################## + +ifdef OPENJDK + BUILD_LIBJPEG_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjpeg/mapfile-vers +else + BUILD_LIBJPEG_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjpeg/mapfile-vers-closed + BUILD_LIBJPEG_CLOSED_SRC := $(JDK_TOPDIR)/src/closed/share/native/sun/awt/image/jpeg + BUILD_LIBJPEG_CLOSED_INCLUDES := -I$(BUILD_LIBJPEG_CLOSED_SRC) +endif + +BUILD_LIBJPEG_REORDER := +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + BUILD_LIBJPEG_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libjpeg/reorder-$(OPENJDK_TARGET_CPU) + endif +endif + +# Suppress gcc warnings like "variable might be clobbered by 'longjmp' +# or 'vfork'": this warning indicates that some variable is placed to +# a register by optimized compiler and it's value might be lost on longjmp(). +# Recommended way to avoid such warning is to declare the variable as +# volatile to prevent the optimization. However, this approach does not +# work because we have to declare all variables as volatile in result. +#ifndef CROSS_COMPILE_ARCH +# CC_43_OR_NEWER := \ +# $(shell $(EXPR) $(CC_MAJORVER) \> 4 \| \ +# \( $(CC_MAJORVER) = 4 \& $(CC_MINORVER) \>= 3 \) ) +# ifeq ($(CC_43_OR_NEWER), 1) +# BUILD_LIBJPEG_CFLAGS_linux += -Wno-clobbered +# endif +#endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBJPEG, \ + LIBRARY := jpeg, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(BUILD_LIBJPEG_CLOSED_SRC) \ + $(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg, \ + LANG := C, \ + OPTIMIZATION := HIGHEST, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(BUILD_LIBJPEG_CLOSED_INCLUDES) \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg, \ + MAPFILE := $(BUILD_LIBJPEG_MAPFILE), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_windows := $(WIN_JAVA_LIB) jvm.lib, \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jpeg.dll" \ + -D "JDK_INTERNAL_NAME=jpeg" \ + -D "JDK_FTYPE=0x2L", \ + REORDER := $(BUILD_LIBJPEG_REORDER), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjpeg, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBJPEG): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBJPEG) + +########################################################################################## + +ifndef OPENJDK + FONT_HEADERS := -I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k + BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libfontmanager/mapfile-vers + LIBFONTMANAGER_EXCLUDE_FILES += freetypeScaler.c +else + FONT_HEADERS := $(FREETYPE2_CFLAGS) + BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libfontmanager/mapfile-vers.openjdk + BUILD_LIBFONTMANAGER_FONTLIB := $(FREETYPE2_LIBS) +endif + +LIBFONTMANAGER_OPTIMIZATION := HIGH + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBFONTMANAGER_EXCLUDE_FILES += X11FontScaler.c \ + X11TextRenderer.c + LIBFONTMANAGER_OPTIMIZATION := HIGHEST +else + LIBFONTMANAGER_EXCLUDE_FILES += fontpath.c \ + lcdglyph.c +endif + +BUILD_LIBFONTMANAGER_CFLAGS_COMMON := \ + $(X_CFLAGS) \ + -DLE_STANDALONE -DHEADLESS \ + $(FONT_HEADERS) \ + -I$(JDK_TOPDIR)/src/share/native/sun/font \ + -I$(JDK_TOPDIR)/src/share/native/sun/font/layout \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d + +# Turn off aliasing with GCC for ExtensionSubtables.cpp +ifeq ($(OPENJDK_TARGET_OS), linux) + BUILD_LIBFONTMANAGER_ExtensionSubtables.cpp_CXXFLAGS := -fno-strict-aliasing +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \ + LIBRARY := fontmanager, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/font \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/font, \ + EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \ + AccelGlyphCache.c, \ + LANG := C++, \ + CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBFONTMANAGER_CFLAGS_COMMON), \ + CXXFLAGS := $(CXXFLAGS_JDKLIB) $(BUILD_LIBFONTMANAGER_CFLAGS_COMMON), \ + OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \ + CFLAGS_windows = -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ + -DCC_NOEX, \ + MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \ + LDFLAGS := $(subst -Xlinker -z -Xlinker defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \ + LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ + LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \ + LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \ + -ljava -ljvm, \ + LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \ + $(WIN_AWT_LIB), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=fontmanager.dll" \ + -D "JDK_INTERNAL_NAME=fontmanager" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfontmanager, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT) + +ifneq (, $(findstring $(OPENJDK_TARGET_OS), solaris macosx)) + $(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT_XAWT) +endif + +BUILD_LIBRARIES += $(BUILD_LIBFONTMANAGER) + +########################################################################################## + +ifndef OPENJDK + + #ifeq ($(OPENJDK_TARGET_OS), linux) + # ifeq ("$(CC_VER_MAJOR)", "3") + # OTHER_LDLIBS += -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic + # endif + #endif + # + # The resulting size of the t2k lib file is (at least on linux) dependant on the order of + # the input .o files. Because of this the new build will differ in size to the old build. + BUILD_LIBT2K_CFLAGS_COMMON := -I$(JDK_TOPDIR)/src/share/native/sun/font \ + -I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \ + -I$(JDK_TOPDIR)/src/closed/share/native/sun/font \ + -I$(JDK_TOPDIR)/src/share/share/native/sun/font \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/font \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d + + $(eval $(call SetupNativeCompilation,BUILD_LIBT2K, \ + LIBRARY := t2k, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/closed/share/native/sun/font \ + $(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \ + $(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k/ttHints, \ + EXCLUDE_FILES := orion.c, \ + LANG := C++, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBT2K_CFLAGS_COMMON), \ + CXXFLAGS := $(CXXFLAGS_JDKLIB) $(BUILD_LIBT2K_CFLAGS_COMMON), \ + CFLAGS_windows = -DCC_NOEX, \ + CXXFLAGS_windows = -DCC_NOEX, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libt2k/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_windows := user32.lib $(JDK_OUTPUTDIR)/objs/libfontmanager/fontmanager.lib, \ + LDFLAGS_SUFFIX_posix := $(LIBM) $(LIBCXX) -lfontmanager -ljava -ljvm -lc, \ + LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=t2k.dll" \ + -D "JDK_INTERNAL_NAME=t2k" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libt2k, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + # t2k is linked against fontmanager + $(BUILD_LIBT2K): $(BUILD_LIBFONTMANAGER) + + BUILD_LIBRARIES += $(BUILD_LIBT2K) +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), windows) + ifeq ($(OPENJDK_TARGET_CPU), x86) + KERNEL32_LIB := kernel32.lib + endif + $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \ + LIBRARY := jawt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows, \ + INCLUDE_FILES := jawt.cpp, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CXXFLAGS_JDKLIB) \ + -EHsc -DUNICODE -D_UNICODE \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \ + advapi32.lib $(WIN_AWT_LIB), \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jawt.dll" \ + -D "JDK_INTERNAL_NAME=jawt" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawt, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBJAWT): $(BUILD_LIBAWT) + + $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX): $(BUILD_LIBJAWT) + $(ECHO) Copying $(@F) + $(CP) $(JDK_OUTPUTDIR)/objs/libjawt/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX) $@ + + BUILD_LIBRARIES += $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX) + +else # OPENJDK_TARGET_OS not windows + + JAWT_LIBS := + ifneq ($(OPENJDK_TARGET_OS), solaris) + JAWT_LIBS += -lawt + endif + + ifndef BUILD_HEADLESS_ONLY + JAWT_LIBS += -lawt_xawt + else + JAWT_LIBS += -lawt_headless + HEADLESS_CFLAG += -DHEADLESS + endif + + JAWT_FILES := jawt.c + ifeq ($(OPENJDK_TARGET_OS), macosx) + JAWT_FILES := jawt.m + JAWT_LIBS := -lawt_lwawt + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \ + LIBRARY := jawt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt \ + $(JDK_TOPDIR)/src/macosx/native/sun/awt, \ + INCLUDE_FILES := $(JAWT_FILES), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB), \ + CFLAGS_linux := $(HEADLESS_CFLAG), \ + CFLAGS_macosx := -I$(JDK_TOPDIR)/src/solaris/native/sun/awt, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjawt/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_solaris := -L$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ + LDFLAGS_SUFFIX_linux := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_solaris := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX) -lXrender, \ + LDFLAGS_SUFFIX_macosx := -Xlinker -rpath -Xlinker @loader_path $(JAWT_LIBS) \ + -framework Cocoa $(LDFLAGS_JDKLIB_SUFFIX), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawt, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + ifndef BUILD_HEADLESS_ONLY + $(BUILD_LIBJAWT): $(BUILD_LIBAWT_XAWT) + else + $(BUILD_LIBJAWT): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)awt_headless$(SHARED_LIBRARY_SUFFIX) + endif + + ifeq ($(OPENJDK_TARGET_OS), macosx) + $(BUILD_LIBJAWT): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)awt_lwawt$(SHARED_LIBRARY_SUFFIX) + endif + +endif # OPENJDK_TARGET_OS + +BUILD_LIBRARIES += $(BUILD_LIBJAWT) + +########################################################################################## + +ifndef OPENJDK + + BUILD_LIBKCMS_EXCLUDE_FILES := + ifeq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBKCMS_EXCLUDE_FILES += ukcpmgr.c unixmem.c + else + BUILD_LIBKCMS_EXCLUDE_FILES += cmmdll.c registry.c spxffile.c sysinfo.c winmem.c wkcpmgr.c + endif + + BUILD_LIBKCMS_FLAGS := $(CFLAGS_JDKLIB) + + ifeq ($(OPENJDK_TARGET_OS), solaris) + # This particular library uses a feature called PIC_CODE_SMALL (on solaris) + # implement it like this...since it's only used here + BUILD_LIBKCMS_FLAGS := $(patsubst -KPIC, -Kpic, $(BUILD_LIBKCMS_FLAGS)) + else ifeq ($(OPENJDK_TARGET_CPU_ARCH), ppc) + BUILD_LIBKCMS_FLAGS := $(patsubst -fPIC, -fpic, $(BUILD_LIBKCMS_FLAGS)) + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBKCMS, \ + LIBRARY := kcms, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms, \ + LANG := C, \ + EXCLUDE_FILES := $(BUILD_LIBKCMS_EXCLUDE_FILES), \ + OPTIMIZATION := LOW, \ + CFLAGS := $(BUILD_LIBKCMS_FLAGS) \ + -DJAVACMM -DFUT_CALC_EX -DNO_FUT_GCONST, \ + CFLAGS_linux := -Wno-missing-field-initializers, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libkcms/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_linux := -lc -lpthread, \ + LDFLAGS_SUFFIX_solaris := -lc, \ + LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib version.lib, \ + LDFLAGS_SUFFIX_posix := -lm -ljava -ljvm, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms/cmm.rc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms/cmm.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=kcms.dll" \ + -D "JDK_INTERNAL_NAME=kcms" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libkcms, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBKCMS): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBKCMS) + +endif + +########################################################################################## + +ifndef OPENJDK + ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + + ifeq ($(shell if test "$(OS_VERSION_MAJOR)" -eq 5 -a "$(OS_VERSION_MINOR)" -le 10; then $(ECHO) ok; fi), ok) + + SUNWJDGA_MAPFILE := + ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) + SUNWJDGA_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjdga/mapfile-vers + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBSUNWJDGA, \ + LIBRARY := sunwjdga, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/solaris/native/sun/jdga, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/javavm/export \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/javavm/export \ + -I$(OPENWIN_HOME)/include, \ + MAPFILE := $(SUNWJDGA_MAPFILE), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -ldga -lX11 $(LIBDL) -lc, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunwjdga, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBSUNWJDGA) + + endif + endif + endif +endif + +########################################################################################## + +ifeq ($(BUILD_HEADLESS), true) + ifneq ($(OPENJDK_TARGET_OS), windows) + + LIBAWT_HEADLESS_DIRS := $(JDK_TOPDIR)/src/share/native/sun/font \ + $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/solaris/native/sun/font \ + $(JDK_TOPDIR)/src/solaris/native/sun/awt \ + $(JDK_TOPDIR)/src/solaris/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/solaris/native/sun/java2d/x11 + + ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBAWT_HEADLESS_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/font + endif + + LIBAWT_HEADLESS_CFLAGS := -DHEADLESS=true \ + -DX11_PATH=\"$(X11_PATH)\" -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ + $(CUPS_CFLAGS) \ + $(X_CFLAGS) \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga \ + $(foreach dir, $(LIBAWT_HEADLESS_DIRS), -I$(dir)) + + ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBAWT_HEADLESS_CFLAGS += \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks + endif + + LIBAWT_HEADLESS_FILES := \ + awt_Font.c \ + HeadlessToolkit.c \ + fontpath.c \ + VDrawingArea.c \ + X11Color.c \ + X11Renderer.c \ + X11PMBlitLoops.c \ + X11SurfaceData.c \ + X11FontScaler_md.c \ + X11TextRenderer_md.c \ + OGLBlitLoops.c \ + OGLBufImgOps.c \ + OGLContext.c \ + OGLFuncs.c \ + OGLMaskBlit.c \ + OGLMaskFill.c \ + OGLPaints.c \ + OGLRenderQueue.c \ + OGLRenderer.c \ + OGLSurfaceData.c \ + OGLTextRenderer.c \ + OGLVertexCache.c \ + GLXGraphicsConfig.c \ + GLXSurfaceData.c \ + AccelGlyphCache.c \ + CUPSfuncs.c + + ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBAWT_HEADLESS_FILES += \ + AWTFont.m \ + AWTStrike.m \ + CCharToGlyphMapper.m \ + CGGlyphImages.m \ + CGGlyphOutlines.m \ + CoreTextSupport.m + endif + + LIBAWT_HEADLESS_REORDER := + ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + LIBAWT_HEADLESS_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libawt_headless/reorder-$(OPENJDK_TARGET_CPU) + endif + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \ + LIBRARY := awt_headless, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBAWT_HEADLESS_DIRS), \ + INCLUDE_FILES := $(LIBAWT_HEADLESS_FILES), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_HEADLESS_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libawt_headless/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..) \ + -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) \ + -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ + LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN)., \ + REORDER := $(LIBAWT_HEADLESS_REORDER), \ + LDFLAGS_SUFFIX_linux := -ljvm -lawt -lm $(LIBDL) -ljava, \ + LDFLAGS_SUFFIX_solaris := $(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc, \ + LDFLAGS_SUFFIX_macosx := -ljvm $(LIBCXX) -lawt $(LIBDL) -ljava \ + -framework Accelerate \ + -framework ApplicationServices \ + -framework Cocoa \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -framework JavaRuntimeSupport, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_headless, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT) + + BUILD_LIBRARIES += $(BUILD_LIBAWT_HEADLESS) + + endif +endif + +########################################################################################## + +ifndef BUILD_HEADLESS_ONLY + LIBSPLASHSCREEN_DIRS := \ + $(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg \ + $(JDK_TOPDIR)/src/share/native/sun/awt/libpng \ + $(JDK_TOPDIR)/src/share/native/sun/awt/splashscreen + + ifeq ($(USE_EXTERNAL_LIBGIF), true) + GIFLIB_LDFLAGS := -lgif + else + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/sun/awt/giflib + GIFLIB_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/awt/giflib + endif + + ifneq ($(OPENJDK_TARGET_OS), macosx) + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/splashscreen + else + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen + endif + + LIBSPLASHSCREEN_CFLAGS := -DSPLASHSCREEN -DPNG_NO_MMX_CODE \ + $(foreach dir, $(LIBSPLASHSCREEN_DIRS), -I$(dir)) + + ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBSPLASHSCREEN_CFLAGS := -I$(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen \ + $(LIBSPLASHSCREEN_CFLAGS) \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks + LIBSPLASHSCREEN_CFLAGS += -DWITH_MACOSX + LIBSPLASHSCREEN_CFLAGS += -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp + + LIBSPLASHSCREEN_java_awt_SplashScreen.c_CFLAGS := -x objective-c -O0 + LIBSPLASHSCREEN_splashscreen_gfx_impl.c_CFLAGS := -x objective-c -O0 + LIBSPLASHSCREEN_splashscreen_gif.c_CFLAGS := -x objective-c -O0 + LIBSPLASHSCREEN_splashscreen_impl.c_CFLAGS := -x objective-c -O0 + LIBSPLASHSCREEN_splashscreen_jpeg.c_CFLAGS := -x objective-c -O0 + LIBSPLASHSCREEN_splashscreen_png.c_CFLAGS := -x objective-c -O0 + LIBSPLASHSCREEN_splashscreen_sys.m_CFLAGS := -O0 + + else ifneq ($(OPENJDK_TARGET_OS), windows) + LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 -I$(OPENWIN_HOME)/include -I$(OPENWIN_HOME)/include/X11/extensions + else + LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32 + endif + + LIBSPLASHSCREEN_LDFLAGS_SUFFIX := + + ifneq ($(USE_EXTERNAL_LIBZ), true) + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 + LIBSPLASHSCREEN_CFLAGS += $(ZLIB_CPPFLAGS) + endif + + ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(LIBM) -lpthread -liconv -losxapp \ + -framework ApplicationServices \ + -framework Foundation \ + -framework Cocoa \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation + else ifneq ($(OPENJDK_TARGET_OS), windows) + LIBSPLASHSCREEN_LDFLAGS_SUFFIX += -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -lX11 -lXext $(LIBM) -lpthread + else # OPENJDK_TARGET_OS + LIBSPLASHSCREEN_LDFLAGS_SUFFIX += kernel32.lib user32.lib gdi32.lib delayimp.lib -DELAYLOAD:user32.dll + endif # OPENJDK_TARGET_OS + + $(eval $(call SetupNativeCompilation,LIBSPLASHSCREEN, \ + LIBRARY := splashscreen, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBSPLASHSCREEN_DIRS), \ + EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(LIBSPLASHSCREEN_CFLAGS) $(CFLAGS_JDKLIB) $(GIFLIB_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libsplashscreen/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(LIBSPLASHSCREEN_LDFLAGS_SUFFIX) $(LIBZ) $(GIFLIB_LDFLAGS), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=splashscreen.dll" \ + -D "JDK_INTERNAL_NAME=splashscreen" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsplashscreen, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(LIBSPLASHSCREEN) + + ifeq ($(OPENJDK_TARGET_OS), macosx) + $(LIBSPLASHSCREEN): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX) + endif + +endif + +########################################################################################## + +ifndef OPENJDK + + LIBDCPR_SRC_DIRS := \ + $(JDK_TOPDIR)/src/closed/share/native/sun/dc/doe \ + $(JDK_TOPDIR)/src/closed/share/native/sun/dc/path \ + $(JDK_TOPDIR)/src/closed/share/native/sun/dc/pr \ + $(JDK_TOPDIR)/src/closed/share/native/sun/dc/util + + LIBDCPR_CFLAGS := $(foreach dir, $(LIBDCPR_SRC_DIRS), -I$(dir)) \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe + + $(eval $(call SetupNativeCompilation,BUILD_LIBDCPR, \ + LIBRARY := dcpr, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBDCPR_SRC_DIRS), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(LIBDCPR_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libdcpr/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(LIBM) $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_posix := -lm, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=dcpr.dll" \ + -D "JDK_INTERNAL_NAME=dcpr" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libdcpr, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBDCPR): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBDCPR) + +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + LIBAWT_LWAWT_FILES := \ + awt.m \ + ApplicationDelegate.m \ + CFRetainedResource.m \ + CGLGraphicsConfig.m \ + CGLSurfaceData.m \ + CGLLayer.m \ + CGraphicsConfig.m \ + CGraphicsDevice.m \ + CGraphicsEnv.m \ + CCharToGlyphMapper.m \ + CSystemColors.m \ + AWTFont.m \ + CGGlyphOutlines.m \ + CGGlyphImages.m \ + CoreTextSupport.m \ + AWTStrike.m \ + InitIDs.m \ + AWTEvent.m \ + AWTView.m \ + AWTWindow.m \ + AWTSurfaceLayers.m \ + CCursorManager.m \ + CClipboard.m \ + CDataTransferer.m \ + CDragSource.m \ + CDragSourceContextPeer.m \ + CDropTarget.m \ + CDropTargetContextPeer.m \ + CInputMethod.m \ + CDesktopPeer.m \ + OSVersion.m \ + DnDUtilities.m \ + CFileDialog.m \ + CImage.m \ + CMenu.m \ + CMenuBar.m \ + CMenuComponent.m \ + CMenuItem.m \ + CPopupMenu.m \ + CRobot.m \ + CTrayIcon.m \ + CWrapper.m \ + JavaAccessibilityAction.m \ + JavaAccessibilityUtilities.m \ + JavaComponentAccessibility.m \ + JavaTextAccessibility.m \ + LWCToolkit.m \ + GeomUtilities.m \ + CPrinterJob.m \ + PrintModel.m \ + PrinterSurfaceData.m \ + PrinterView.m \ + QuartzSurfaceData.m \ + QuartzRenderer.m \ + CTextPipe.m \ + ImageSurfaceData.m \ + awt_DrawingSurface.m \ + \ + OGLBlitLoops.c \ + OGLBufImgOps.c \ + OGLContext.c \ + OGLFuncs.c \ + OGLMaskBlit.c \ + OGLMaskFill.c \ + OGLPaints.c \ + OGLRenderQueue.c \ + OGLRenderer.c \ + OGLSurfaceData.c \ + OGLTextRenderer.c \ + OGLVertexCache.c \ + AccelGlyphCache.c \ + CUPSfuncs.c + + + LIBAWT_LWAWT_DIRS := \ + $(JDK_TOPDIR)/src/macosx/native/sun/awt \ + $(JDK_TOPDIR)/src/macosx/native/sun/font \ + $(JDK_TOPDIR)/src/macosx/native/sun/java2d/opengl \ + $(JDK_TOPDIR)/src/solaris/native/sun/awt \ + $(JDK_TOPDIR)/src/share/native/sun/font \ + $(JDK_TOPDIR)/src/share/native/sun/java2d/opengl \ + + $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_LWAWT, \ + LIBRARY := awt_lwawt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBAWT_LWAWT_DIRS), \ + LANG := C, \ + INCLUDE_FILES := $(LIBAWT_LWAWT_FILES), \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(X_CFLAGS) \ + $(X_LIBS) \ + $(foreach dir, $(LIBAWT_LWAWT_DIRS), -I$(dir)) \ + -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/solaris/native/sun/java2d \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/loops \ + -I$(JDK_TOPDIR)/src/share/native/sun/java2d/pipe \ + -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_macosx := -lawt -lmlib_image -losxapp -ljvm $(LIBM) \ + -framework Accelerate \ + -framework ApplicationServices \ + -framework AudioToolbox \ + -framework Carbon \ + -framework Cocoa \ + -framework Security \ + -framework ExceptionHandling \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -framework JavaRuntimeSupport \ + -framework OpenGL \ + -framework QuartzCore -ljava, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_lwawt, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBAWT_LWAWT) + + $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBAWT) + + $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBMLIB_IMAGE) + + $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBOSXAPP) + + $(BUILD_LIBAWT_LWAWT): $(BUILD_LIBJAVA) + +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + $(eval $(call SetupNativeCompilation,BUILD_LIBOSXUI, \ + LIBRARY := osxui, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/macosx/native/com/apple/laf, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/macosx/native/com/apple/laf \ + -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ + -I$(JDK_TOPDIR)/src/macosx/native/sun/awt \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + -Xlinker -rpath -Xlinker @loader_path, \ + LDFLAGS_SUFFIX_macosx := -lawt -losxapp -lawt_lwawt \ + -framework Cocoa \ + -framework Carbon \ + -framework ApplicationServices \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -framework JavaRuntimeSupport \ + -ljava -ljvm, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libosxui, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBOSXUI) + + $(BUILD_LIBOSXUI): $(BUILD_LIBAWT) + + $(BUILD_LIBOSXUI): $(BUILD_LIBOSXAPP) + + $(BUILD_LIBOSXUI): $(BUILD_LIBAWT_LWAWT) + + #$(BUILD_LIBOSXUI): $(BUILD_LIBJAVA) + +endif diff --git a/jdk/makefiles/lib/CoreLibraries.gmk b/jdk/makefiles/lib/CoreLibraries.gmk new file mode 100644 index 00000000000..29c1d5fc08a --- /dev/null +++ b/jdk/makefiles/lib/CoreLibraries.gmk @@ -0,0 +1,510 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +WIN_VERIFY_LIB := $(JDK_OUTPUTDIR)/objs/libverify/verify.lib + +########################################################################################## + +BUILD_LIBFDLIBM_OPTIMIZATION := HIGH + +ifneq ($(OPENJDK_TARGET_OS), solaris) + BUILD_LIBFDLIBM_OPTIMIZATION := NONE +endif + +ifneq ($(OPENJDK_TARGET_OS), macosx) + $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM, \ + STATIC_LIBRARY := fdlibm, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ + SRC := $(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/src, \ + LANG := C, \ + OPTIMIZATION := $(BUILD_LIBFDLIBM_OPTIMIZATION), \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include, \ + CFLAGS_windows_debug := -DLOGGING, \ + ARFLAGS := $(ARFLAGS), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +else + + # On macosx the old build does partial (incremental) linking of fdlibm instead of + # a plain static library. + $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM_MAC, \ + LIBRARY := fdlibm, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ + SRC := $(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/src, \ + LANG := C, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include, \ + LDFLAGS := -nostdlib -r -arch x86_64, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBFDLIBM := $(JDK_OUTPUTDIR)/objs/$(LIBRARY_PREFIX)fdlibm$(STATIC_LIBRARY_SUFFIX) + $(BUILD_LIBFDLIBM): $(BUILD_LIBFDLIBM_MAC) + $(call install-file) + +endif + +BUILD_LIBRARIES += $(BUILD_LIBFDLIBM) + +########################################################################################## + +BUILD_LIBVERIFY_SRC := check_code.c check_format.c + +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU) + endif +endif + +LIBVERIFY_OPTIMIZATION := HIGH +ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) + ifeq ($(ENABLE_DEBUG_SYMBOLS), true) + LIBVERIFY_OPTIMIZATION := LOW + endif +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBVERIFY, \ + LIBRARY := verify, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/common, \ + INCLUDE_FILES := $(BUILD_LIBVERIFY_SRC), \ + LANG := C, \ + OPTIMIZATION := $(LIBVERIFY_OPTIMIZATION), \ + CFLAGS := $(CFLAGS_JDKLIB), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libverify/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_posix := -ljvm -lc, \ + LDFLAGS_SUFFIX_windows := jvm.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=verify.dll" \ + -D "JDK_INTERNAL_NAME=verify" \ + -D "JDK_FTYPE=0x2L", \ + REORDER := $(BUILD_LIBVERIFY_REORDER), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libverify, \ + DEBUG_SYMBOLS := true)) + +BUILD_LIBRARIES += $(BUILD_LIBVERIFY) + +########################################################################################## + +LIBJAVA_SRC_DIRS := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/lang \ + $(JDK_TOPDIR)/src/share/native/java/lang \ + $(JDK_TOPDIR)/src/share/native/java/lang/ref \ + $(JDK_TOPDIR)/src/share/native/java/lang/reflect \ + $(JDK_TOPDIR)/src/share/native/java/io \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io \ + $(JDK_TOPDIR)/src/share/native/java/nio \ + $(JDK_TOPDIR)/src/share/native/java/security \ + $(JDK_TOPDIR)/src/share/native/common \ + $(JDK_TOPDIR)/src/share/native/sun/misc \ + $(JDK_TOPDIR)/src/share/native/sun/reflect \ + $(JDK_TOPDIR)/src/share/native/java/util \ + $(JDK_TOPDIR)/src/share/native/java/util/concurrent/atomic \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/common \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/util + +ifneq ($(OPENJDK_TARGET_OS), macosx) + LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/util/locale/provider +else + LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/util/locale/provider +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/provider \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/io +endif + +LIBJAVA_CFLAGS := $(foreach dir, $(LIBJAVA_SRC_DIRS), -I$(dir)) \ + -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include \ + -DARCHPROPNAME='"$(OPENJDK_TARGET_CPU_OSARCH)"' + +LIBJAVA_CFLAGS += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ + -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \ + -DJDK_MICRO_VERSION='"$(JDK_MICRO_VERSION)"' \ + -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' + +ifneq (, $(JDK_UPDATE_VERSION)) + LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"' +endif + +LIBJAVA_EXCLUDE_FILES := check_code.c check_format.c jspawnhelper.c + +ifneq ($(OPENJDK_TARGET_OS), macosx) + LIBJAVA_EXCLUDE_FILES += java_props_macosx.c +else + BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c + BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBJAVA_EXCLUDE_FILES += \ + UNIXProcess_md.c \ + UnixFileSystem_md.c \ + FileSystemPreferences.c +else + LIBJAVA_EXCLUDE_FILES += \ + ProcessImpl_md.c \ + WinNTFileSystem_md.c \ + dirent_md.c \ + WindowsPreferences.c \ + sun/security/provider/WinCAPISeedGenerator.c \ + sun/io/Win32ErrorMode.c +endif + +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + LIBJAVA_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libjava/reorder-$(OPENJDK_TARGET_CPU) + endif +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \ + LIBRARY := java, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBJAVA_SRC_DIRS), \ + EXCLUDES := fdlibm/src zip, \ + EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \ + LANG := C, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(LIBJAVA_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjava/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_posix := -ljvm -lverify, \ + LDFLAGS_SUFFIX_solaris := -lsocket -lnsl -lscf $(LIBDL) $(BUILD_LIBFDLIBM) -lc, \ + LDFLAGS_SUFFIX_linux := $(LIBDL) $(BUILD_LIBFDLIBM), \ + LDFLAGS_SUFFIX_macosx := -L$(JDK_OUTPUTDIR)/objs/ -lfdlibm \ + -framework CoreFoundation \ + -framework Foundation \ + -framework Security -framework SystemConfiguration, \ + LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \ + jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ + shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \ + advapi32.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=java.dll" \ + -D "JDK_INTERNAL_NAME=java" \ + -D "JDK_FTYPE=0x2L", \ + REORDER := $(LIBJAVA_REORDER), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjava, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +BUILD_LIBRARIES += $(BUILD_LIBJAVA) + +$(BUILD_LIBJAVA): $(LIBJLI_BINARY) + +$(BUILD_LIBJAVA): $(BUILD_LIBVERIFY) + +$(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM) + +########################################################################################## + +BUILD_LIBZIP_EXCLUDES := +ifeq ($(USE_EXTERNAL_LIBZ), true) + LIBZ := -lz + LIBZIP_EXCLUDES += zlib-1.2.5 +else + ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 +endif + +BUILD_LIBZIP_REORDER := +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + BUILD_LIBZIP_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU) + endif +endif + +ifeq ($(LIBZIP_CAN_USE_MMAP), true) + BUILD_LIBZIP_MMAP := -DUSE_MMAP +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \ + LIBRARY := zip, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip, \ + EXCLUDES := $(LIBZIP_EXCLUDES), \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(ZLIB_CPPFLAGS) \ + -I$(JDK_TOPDIR)/src/share/native/java/io \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io, \ + CFLAGS_posix := $(BUILD_LIBZIP_MMAP) -UDEBUG, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libzip/mapfile-vers, \ + REORDER := $(BUILD_LIBZIP_REORDER), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(EXPORT_ZIP_FUNCS), \ + LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \ + -export:ZIP_ReadEntry -export:ZIP_GetNextEntry jvm.lib \ + $(WIN_JAVA_LIB), \ + LDFLAGS_SUFFIX_linux := -ljvm -ljava $(LIBZ), \ + LDFLAGS_SUFFIX_solaris := -ljvm -ljava $(LIBZ) -lc, \ + LDFLAGS_SUFFIX_macosx := $(LIBZ) -ljava -ljvm, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=zip.dll" \ + -D "JDK_INTERNAL_NAME=zip" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libzip, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + +$(BUILD_LIBZIP): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBZIP) + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \ + LIBRARY := unpack, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/com/sun/java/util/jar/pack, \ + EXCLUDE_FILES := main.cpp, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CXXFLAGS_JDKLIB) \ + -DNO_ZLIB -DUNPACK_JNI -DFULL, \ + CFLAGS_release := -DPRODUCT, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libunpack/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_windows := -map:$(JDK_OUTPUTDIR)/objs/unpack.map -debug \ + jvm.lib $(WIN_JAVA_LIB), \ + LDFLAGS_SUFFIX_posix := -ljvm $(LIBCXX) -ljava -lc, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libunpack, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=unpack.dll" \ + -D "JDK_INTERNAL_NAME=unpack" \ + -D "JDK_FTYPE=0x2L", \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBUNPACK): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBUNPACK) + +ifeq ($(OPENJDK_TARGET_OS), windows) + $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)unpack.map: $(BUILD_LIBUNPACK) + $(ECHO) Copying $(@F) + $(CP) $(patsubst %$(SHARED_LIBRARY_SUFFIX), %.map, $<) $@ + + $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)unpack.pdb: $(BUILD_LIBUNPACK) + $(ECHO) Copying $(@F) + $(CP) $(patsubst %$(SHARED_LIBRARY_SUFFIX), %.pdb, $<) $@ +endif + +########################################################################################## + +BUILD_LIBJLI_SRC_DIRS := $(JDK_TOPDIR)/src/share/bin $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/bin +LIBJLI_CFLAGS := $(CFLAGS_JDKLIB) $(foreach dir, $(BUILD_LIBJLI_SRC_DIRS), -I$(dir)) + +BUILD_LIBJLI_FILES := \ + java.c \ + splashscreen_stubs.c \ + parse_manifest.c \ + version_comp.c \ + wildcard.c \ + jli_util.c + +ifeq ($(JVM_VARIANT_ZERO), true) + ERGO_FAMILY := zero +else + ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86) + ERGO_FAMILY := i586 + else + ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH) + endif +endif + +ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBJLI_CFLAGS += -I$(JDK_TOPDIR)/src/macosx/bin + BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/bin + BUILD_LIBJLI_FILES += java_md_common.c java_md_macosx.c + + BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c + BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBJLI_FILES += java_md.c \ + cmdtoargs.c + # Staticically link with c runtime on windows. + LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS)) +else ifneq ($(OPENJDK_TARGET_OS), macosx) + + BUILD_LIBJLI_FILES += java_md_common.c + BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c + + ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c + + # if the architecture specific ergo file exists then + # use it, else use the generic definitions from ergo.c + ifneq ($(wildcard $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/bin/$(ERGO_ARCH_FILE)), ) + BUILD_LIBJLI_FILES += $(ERGO_ARCH_FILE) + else # !ERGO_ARCH_FILE + LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO + endif # ERGO_ARCH_FILE +endif #WINDOWS + +# Append defines depending on target platform +LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS) + +ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" +endif + +ifneq ($(USE_EXTERNAL_LIBZ), true) + BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 + LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS) + BUILD_LIBJLI_FILES += \ + inflate.c \ + inftrees.c \ + inffast.c \ + zadler32.c \ + zcrc32.c \ + zutil.c +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE) +else + LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \ + LIBRARY := jli, \ + OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \ + SRC := $(BUILD_LIBJLI_SRC_DIRS), \ + INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ + LANG := C, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(LIBJLI_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjli/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + LDFLAGS_macosx := -framework Cocoa -framework Security -framework ApplicationServices, \ + LDFLAGS_SUFFIX_solaris := $(LIBZ) $(LIBDL) -lc, \ + LDFLAGS_SUFFIX_linux := $(LIBZ) $(LIBDL) -lc -lpthread, \ + LDFLAGS_SUFFIX_macosx := $(LIBZ), \ + LDFLAGS_SUFFIX_windows := \ + -export:JLI_Launch \ + -export:JLI_ManifestIterate \ + -export:JLI_SetTraceLauncher \ + -export:JLI_ReportErrorMessage \ + -export:JLI_ReportErrorMessageSys \ + -export:JLI_ReportMessage \ + -export:JLI_ReportExceptionDescription \ + -export:JLI_MemAlloc \ + -export:JLI_CmdToArgs \ + -export:JLI_GetStdArgc \ + -export:JLI_GetStdArgs \ + advapi32.lib \ + comctl32.lib \ + user32.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jli.dll" \ + -D "JDK_INTERNAL_NAME=jli" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjli, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +BUILD_LIBRARIES += $(BUILD_LIBJLI) + +# On windows, the static library has the same suffix as the import library created by +# with the shared library, so the static library is given a different name. No harm +# in doing it for all platform to reduce complexity. +ifeq ($(OPENJDK_TARGET_OS), windows) + $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ + STATIC_LIBRARY := jli_static, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ + SRC := $(BUILD_LIBJLI_SRC_DIRS), \ + INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ + LANG := C, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \ + ARFLAGS := $(ARFLAGS), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjli_static, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBJLI_STATIC) + +else ifeq ($(OPENJDK_TARGET_OS), macosx) + # + # On macosx they do partial (incremental) linking of libjli_static.a + # code it here...rather than add support to NativeCompilation + # as this is first time I see it + $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ + LIBRARY := jli_static, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ + SRC := $(BUILD_LIBJLI_SRC_DIRS), \ + INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ + LANG := C, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \ + LDFLAGS := -nostdlib -r, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjli_static, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(JDK_OUTPUTDIR)/objs/libjli_static.a: $(BUILD_LIBJLI_STATIC) + $(call install-file) + + BUILD_LIBRARIES += $(JDK_OUTPUTDIR)/objs/libjli_static.a +endif + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBNPT, \ + LIBRARY := npt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/npt $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/npt \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnpt/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_macosx := -liconv, \ + LDFLAGS_SUFFIX_windows := -export:nptInitialize -export:nptTerminate, \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=npt.dll" \ + -D "JDK_INTERNAL_NAME=npt" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libnpt, \ + DEBUG_SYMBOLS := true)) + +BUILD_LIBRARIES += $(BUILD_LIBNPT) diff --git a/jdk/makefiles/lib/NetworkingLibraries.gmk b/jdk/makefiles/lib/NetworkingLibraries.gmk new file mode 100644 index 00000000000..546565af91b --- /dev/null +++ b/jdk/makefiles/lib/NetworkingLibraries.gmk @@ -0,0 +1,98 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/share/native/java/net \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/dns \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/spi + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/www/protocol/http/ntlm +else + LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/net/sdp +endif + +LIBNET_CFLAGS := $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir)) + +LIBNET_EXCLUDE_FILES := +ifneq ($(OPENJDK_TARGET_OS), linux) + LIBNET_EXCLUDE_FILES += linux_close.c +endif + +ifneq ($(OPENJDK_TARGET_OS), macosx) + LIBNET_EXCLUDE_FILES += bsd_close.c +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBNET_EXCLUDE_FILES += PlainSocketImpl.c PlainDatagramSocketImpl.c SdpSupport.c +else + LIBNET_EXCLUDE_FILES += TwoStacksPlainSocketImpl.c DualStackPlainSocketImpl.c \ + TwoStacksPlainDatagramSocketImpl.c DualStackPlainDatagramSocketImpl.c \ + NTLMAuthSequence.c NetworkInterface_winXP.c +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \ + LIBRARY := net, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBNET_SRC_DIRS), \ + EXCLUDE_FILES := $(LIBNET_EXCLUDE_FILES), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(LIBNET_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnet/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_macosx := -ljvm -ljava, \ + LDFLAGS_SUFFIX_solaris := -ljvm -ljava -lnsl -lsocket $(LIBDL) -lc, \ + LDFLAGS_SUFFIX_linux := $(LIBDL) -ljvm -lpthread -ljava, \ + LDFLAGS_SUFFIX_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \ + delayimp.lib $(WIN_JAVA_LIB) advapi32.lib \ + -DELAYLOAD:secur32.dll -DELAYLOAD:iphlpapi.dll, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=net.dll" \ + -D "JDK_INTERNAL_NAME=net" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libnet, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBNET): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBNET) + +$(JDK_OUTPUTDIR)/lib/net.properties: $(JDK_TOPDIR)/src/share/lib/net.properties + $(ECHO) $(LOG_INFO) Copying $(@F) + $(call install-file) + +COPY_FILES += $(JDK_OUTPUTDIR)/lib/net.properties + +ifeq ($(OPENJDK_TARGET_OS), solaris) + $(JDK_OUTPUTDIR)/lib/sdp/sdp.conf.template: $(JDK_TOPDIR)/src/${OPENJDK_TARGET_OS_API_DIR}/lib/sdp/sdp.conf.template + $(ECHO) $(LOG_INFO) Copying $(@F) + $(call install-file) + + COPY_FILES += $(JDK_OUTPUTDIR)/lib/sdp/sdp.conf.template +endif diff --git a/jdk/makefiles/lib/NioLibraries.gmk b/jdk/makefiles/lib/NioLibraries.gmk new file mode 100644 index 00000000000..2896eeea84f --- /dev/null +++ b/jdk/makefiles/lib/NioLibraries.gmk @@ -0,0 +1,185 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +BUILD_LIBNIO_SRC := \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/nio \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/ch \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/fs + +BUILD_LIBNIO_CFLAGS := \ + -I$(JDK_TOPDIR)/src/share/native/sun/nio/ch \ + -I$(JDK_TOPDIR)/src/share/native/java/io \ + -I$(JDK_TOPDIR)/src/share/native/java/net \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net + +BUILD_LIBNIO_FILES := \ + DatagramChannelImpl.c \ + DatagramDispatcher.c \ + FileChannelImpl.c \ + FileDispatcherImpl.c \ + FileKey.c \ + IOUtil.c \ + MappedByteBuffer.c \ + Net.c \ + ServerSocketChannelImpl.c \ + SocketChannelImpl.c \ + SocketDispatcher.c + +ifeq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBNIO_FILES += \ + Iocp.c \ + RegistryFileTypeDetector.c \ + WindowsAsynchronousFileChannelImpl.c \ + WindowsAsynchronousServerSocketChannelImpl.c \ + WindowsAsynchronousSocketChannelImpl.c \ + WindowsNativeDispatcher.c \ + WindowsSelectorImpl.c +endif + +ifeq ($(OPENJDK_TARGET_OS), linux) + BUILD_LIBNIO_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS) + BUILD_LIBNIO_FILES += \ + EPoll.c \ + EPollArrayWrapper.c \ + EPollPort.c \ + InheritedChannel.c \ + NativeThread.c \ + PollArrayWrapper.c \ + UnixAsynchronousServerSocketChannelImpl.c \ + UnixAsynchronousSocketChannelImpl.c \ + GnomeFileTypeDetector.c \ + MagicFileTypeDetector.c \ + LinuxNativeDispatcher.c \ + LinuxWatchService.c \ + UnixCopyFile.c \ + UnixNativeDispatcher.c +endif + +ifeq ($(OPENJDK_TARGET_OS), macosx) + BUILD_LIBNIO_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS) + BUILD_LIBNIO_SRC += $(JDK_TOPDIR)/src/macosx/native/sun/nio/ch + BUILD_LIBNIO_FILES += \ + InheritedChannel.c \ + NativeThread.c \ + PollArrayWrapper.c \ + UnixAsynchronousServerSocketChannelImpl.c \ + UnixAsynchronousSocketChannelImpl.c \ + BsdNativeDispatcher.c \ + MacOSXNativeDispatcher.c \ + UnixCopyFile.c \ + UnixNativeDispatcher.c \ + KQueue.c \ + KQueuePort.c \ + KQueueArrayWrapper.c +endif + +ifeq ($(OPENJDK_TARGET_OS), solaris) + BUILD_LIBNIO_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS) + BUILD_LIBNIO_FILES += \ + DevPollArrayWrapper.c \ + InheritedChannel.c \ + NativeThread.c \ + PollArrayWrapper.c \ + SolarisEventPort.c \ + UnixAsynchronousServerSocketChannelImpl.c \ + UnixAsynchronousSocketChannelImpl.c \ + GnomeFileTypeDetector.c \ + SolarisNativeDispatcher.c \ + SolarisWatchService.c \ + UnixCopyFile.c \ + UnixNativeDispatcher.c +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \ + LIBRARY := nio, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(BUILD_LIBNIO_SRC), \ + INCLUDE_FILES := $(BUILD_LIBNIO_FILES), \ + LANG := C, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(BUILD_LIBNIO_CFLAGS), \ + MAPFILE := $(BUILD_LIBNIO_MAPFILE), \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(BUILD_LIBNIO_LDFLAGS) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_linux := -ljava -lnet -lpthread $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -ljvm -lsocket -lposix4 $(LIBDL) \ + -lsendfile -ljava -lnet -lc, \ + LDFLAGS_SUFFIX_windows := jvm.lib ws2_32.lib $(WIN_JAVA_LIB) \ + $(JDK_OUTPUTDIR)/objs/libnet/net.lib \ + advapi32.lib, \ + LDFLAGS_SUFFIX_macosx := -ljava -lnet -pthread -framework CoreFoundation, \ + LDFLAGS_SUFFIX :=, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=nio.dll" \ + -D "JDK_INTERNAL_NAME=nio" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libnio, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +BUILD_LIBRARIES += $(BUILD_LIBNIO) + +$(BUILD_LIBNIO): $(BUILD_LIBNET) + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS_API), posix) + + ifneq ($(OPENJDK_TARGET_OS), macosx) + + SCTP_WERROR := -Werror + ifeq ($(OPENJDK_TARGET_CPU_ARCH), ppc) + SCTP_WERROR := + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBSCTP, \ + LIBRARY := sctp, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/ch/sctp, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/sun/nio/ch \ + -I$(JDK_TOPDIR)/src/share/native/sun/nio/ch/sctp \ + -I$(JDK_TOPDIR)/src/share/native/java/net \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/nio/ch \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/net, \ + CFLAGS_linux := $(SCTP_WERROR), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libsctp/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_linux := -lpthread $(LIBDL) -ljava -ljvm, \ + LDFLAGS_SUFFIX_posix := -lnio -lnet, \ + LDFLAGS_SUFFIX_solaris := -lsocket -ljava -ljvm -lc, \ + LDFLAGS_SUFFIX_macosx := -ljava -ljvm, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsctp, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBSCTP) + + $(BUILD_LIBSCTP): $(BUILD_LIBNIO) + endif +endif diff --git a/jdk/makefiles/lib/PlatformLibraries.gmk b/jdk/makefiles/lib/PlatformLibraries.gmk new file mode 100644 index 00000000000..2000757cd19 --- /dev/null +++ b/jdk/makefiles/lib/PlatformLibraries.gmk @@ -0,0 +1,286 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + $(eval $(call SetupNativeCompilation,BUILD_LIBAPPLESCRIPTENGINE, \ + LIBRARY := AppleScriptEngine, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/macosx/native/apple/applescript, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/macosx/native/apple/applescript \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := -framework Cocoa \ + -framework Carbon \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + $(LDFLAGS_JDKLIB_SUFFIX), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libAppleScriptEngine, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBAPPLESCRIPTENGINE): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBAPPLESCRIPTENGINE) + +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + $(eval $(call SetupNativeCompilation,BUILD_LIBOSXAPP, \ + LIBRARY := osxapp, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/macosx/native/sun/osxapp, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ + -I$(JDK_OUTPUTDIR)/gensrc/sun/osxapp \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_macosx := \ + -framework Accelerate \ + -framework ApplicationServices \ + -framework AudioToolbox \ + -framework Carbon \ + -framework Cocoa \ + -framework Security \ + -framework ExceptionHandling \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -framework JavaRuntimeSupport \ + -framework OpenGL \ + -framework IOSurface \ + -framework QuartzCore, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libosxapp, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBOSXAPP) + +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + LIBOSX_DIRS := \ + $(JDK_TOPDIR)/src/macosx/native/com/apple/concurrent \ + $(JDK_TOPDIR)/src/macosx/native/java/util \ + $(JDK_TOPDIR)/src/macosx/native/com/apple/eio \ + $(JDK_TOPDIR)/src/macosx/native/apple/security \ + $(JDK_TOPDIR)/src/macosx/native/apple/launcher + + $(eval $(call SetupNativeCompilation,BUILD_LIBOSX, \ + LIBRARY := osx, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBOSX_DIRS), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(foreach dir, $(LIBOSX_DIRS), -I$(dir)) \ + -I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -F/System/Library/Frameworks/ApplicationServices.framework/Frameworks, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_macosx := \ + -losxapp \ + -framework Cocoa \ + -framework ApplicationServices \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -framework JavaRuntimeSupport \ + -framework Security \ + -framework SystemConfiguration \ + $(LDFLAGS_JDKLIB_SUFFIX), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libosx, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBOSX) + + $(BUILD_LIBOSX): $(BUILD_LIBOSXAPP) + + $(BUILD_LIBOSX): $(BUILD_LIBJAVA) + +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + # Ugly hack to mimic behaviour in old build where this is built as an xcode project. + SET_SHARED_LIBRARY_NAME = -Xlinker -install_name -Xlinker /usr/local/lib/libJObjC.dylib + + $(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC32, \ + LIBRARY := JObjC, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \ + SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \ + $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := -fpascal-strings \ + -fobjc-gc \ + -gdwarf-2 \ + $(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -m32, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + -m32, \ + LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -lffi, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC64, \ + LIBRARY := JObjC, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \ + SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \ + $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := -fpascal-strings \ + -fobjc-gc \ + -gdwarf-2 \ + $(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + , \ + LDFLAGS := -fpascal-strings \ + -fobjc-gc \ + -gdwarf-2 \ + $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \ + -F/System/Library/Frameworks/JavaVM.framework/Frameworks \ + -framework JavaNativeFoundation \ + -lffi, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX): $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64) + $(LIPO) -create -output $@ $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64) + + BUILD_LIBRARIES += $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX) + +endif + +########################################################################################## + +ifndef OPENJDK + ifeq ($(OPENJDK_TARGET_OS), windows) + + ACCESSBRIDGE_SRCDIR := $(JDK_TOPDIR)/src/closed/windows/native/sun/bridge + + define SetupAccessBridge + # Parameter 1 Suffix + # Parameter 2 Machine + # Parameter 3 ACCESSBRIDGE_ARCH_ suffix + + $(call SetupNativeCompilation,BUILD_JAWTACCESSBRIDGE$1, \ + LIBRARY = JAWTAccessBridge$1, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(ACCESSBRIDGE_SRCDIR), \ + INCLUDE_FILES := JAWTAccessBridge.cpp, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -DACCESSBRIDGE_ARCH_$3, \ + LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ + winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib \ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ + -subsystem:windows -machine:$2 \ + -def:$(ACCESSBRIDGE_SRCDIR)/JAWTAccessBridge.DEF, \ + VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ + RC_FLAGS := $(RC_FLAGS), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawtaccessbridge$1, \ + DEBUG_SYMBOLS := true) + + $$(BUILD_JAWTACCESSBRIDGE$1): $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX) + + $(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1, \ + LIBRARY = JavaAccessBridge$1, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(ACCESSBRIDGE_SRCDIR), \ + INCLUDE_FILES := AccessBridgeATInstance.cpp AccessBridgeDebug.cpp \ + AccessBridgeJavaEntryPoints.cpp \ + AccessBridgeMessages.cpp JavaAccessBridge.cpp, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -DACCESSBRIDGE_ARCH_$3, \ + LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ + winspool.lib comdlg32.lib advapi32.lib shell32.lib \ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ + -subsystem:windows -machine:$2 \ + -def:$(ACCESSBRIDGE_SRCDIR)/JavaAccessBridge.DEF, \ + VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ + RC_FLAGS := $(RC_FLAGS), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjavaaccessbridge$1, \ + DEBUG_SYMBOLS := true) + + $(call SetupNativeCompilation,BUILD_WINDOWSACCESSBRIDGE$1, \ + LIBRARY = WindowsAccessBridge$1, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(ACCESSBRIDGE_SRCDIR), \ + INCLUDE_FILES := AccessBridgeJavaVMInstance.cpp AccessBridgeMessageQueue.cpp \ + AccessBridgeMessages.cpp AccessBridgeWindowsEntryPoints.cpp \ + WinAccessBridge.cpp AccessBridgeDebug.cpp \ + AccessBridgeEventHandler.cpp, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(filter-out -MD, $(CFLAGS_JDKLIB)) -MT \ + -DACCESSBRIDGE_ARCH_$3, \ + LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ + winspool.lib comdlg32.lib advapi32.lib shell32.lib \ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ + -subsystem:windows -machine:$2 \ + -def:$(ACCESSBRIDGE_SRCDIR)/WinAccessBridge.DEF, \ + VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc, \ + RC_FLAGS := $(RC_FLAGS), \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libwindowsaccessbridge$1, \ + DEBUG_SYMBOLS := true) + + BUILD_LIBRARIES += $$(BUILD_JAWTACCESSBRIDGE$1) $$(BUILD_JAVAACCESSBRIDGE$1) \ + $$(BUILD_WINDOWSACCESSBRIDGE$1) + + endef + + ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) + $(eval $(call SetupAccessBridge,-32,I386,32)) + $(eval $(call SetupAccessBridge,,I386,LEGACY)) + else + $(eval $(call SetupAccessBridge,-64,X64,64)) + endif + endif +endif diff --git a/jdk/makefiles/lib/SecurityLibraries.gmk b/jdk/makefiles/lib/SecurityLibraries.gmk new file mode 100644 index 00000000000..779504f5f84 --- /dev/null +++ b/jdk/makefiles/lib/SecurityLibraries.gmk @@ -0,0 +1,289 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +LIBJAAS_MAPFILE := +ifneq ($(OPENJDK_TARGET_OS), solaris) + LIBJAAS_EXCLUDE_FILES := Solaris.c +else + # only on solaris...wonder why + LIBJAAS_MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjaas/mapfile-vers +endif + +LIBJAAS_NAME := jaas_unix +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBJAAS_NAME := jaas_nt +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \ + LIBRARY := $(LIBJAAS_NAME), \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/com/sun/security/auth/module, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB), \ + MAPFILE := $(LIBJAAS_MAPFILE), \ + LDFLAGS := $(filter-out -ljava, $(LDFLAGS_JDKLIB)) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \ + LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + EXCLUDE_FILES := $(LIBJAAS_EXCLUDE_FILES), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=$(LIBJAAS_NAME).dll" \ + -D "JDK_INTERNAL_NAME=$(LIBJAAS_NAME)" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjaas, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBJAAS): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBJAAS) + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PCSC, \ + LIBRARY := j2pcsc, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/security/smartcardio \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/smartcardio, \ + LANG := C, \ + CFLAGS_posix := -D__sun_jdk, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/sun/security/smartcardio \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/smartcardio \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/smartcardio/MUSCLE, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2pcsc/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_posix := $(LIBDL), \ + LDFLAGS_SUFFIX_windows := winscard.lib, \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=j2pcsc.dll" \ + -D "JDK_INTERNAL_NAME=j2pcsc" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2pcsc, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +BUILD_LIBRARIES += $(BUILD_LIBJ2PCSC) + +########################################################################################## + +ifneq ($(OPENJDK_TARGET_OS), windows) + $(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS, \ + LIBRARY := j2gss, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/security/jgss/wrapper \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/jgss/wrapper, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/sun/security/jgss/wrapper \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/jgss/wrapper, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2gss/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2gss, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBJ2GSS) +endif + +########################################################################################## + +ifneq ($(BUILD_CRYPTO), no) + BUILD_LIBKRB5_NAME := + ifeq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBKRB5_NAME := w2k_lsa_auth + BUILD_LIBKRB5_SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5 + BUILD_LIBKRB5_LIBS := advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \ + gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib + else ifeq ($(OPENJDK_TARGET_OS), macosx) + BUILD_LIBKRB5_NAME := osxkrb5 + BUILD_LIBKRB5_SRC := $(JDK_TOPDIR)/src/share/native/sun/security/krb5 + BUILD_LIBKRB5_LIBS := -framework Kerberos + endif + + ifneq ($(BUILD_LIBKRB5_NAME), ) + $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5, \ + LIBRARY := $(BUILD_LIBKRB5_NAME), \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(BUILD_LIBKRB5_SRC), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/sun/security/krb5 \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(BUILD_LIBKRB5_LIBS), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=$(BUILD_LIBKRB5_NAME).dll" \ + -D "JDK_INTERNAL_NAME=$(BUILD_LIBKRB5_NAME)" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libkrb5, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBKRB5) + endif +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), windows) + + $(eval $(call SetupNativeCompilation,BUILD_LIBSUNMSCAPI, \ + LIBRARY := sunmscapi, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := Crypt32.Lib advapi32.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=sunmscapi.dll" \ + -D "JDK_INTERNAL_NAME=sunmscapi" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunmscapi, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBSUNMSCAPI) +endif + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \ + LIBRARY := j2pkcs11, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/security/pkcs11 \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11 \ + $(JDK_TOPDIR)/src/share/native/sun/security/pkcs11/wrapper \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11/wrapper, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/sun/security/pkcs11 \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11 \ + -I$(JDK_TOPDIR)/src/share/native/sun/security/pkcs11/wrapper \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/pkcs11/wrapper, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2pkcs11/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_posix := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=j2pkcs11.dll" \ + -D "JDK_INTERNAL_NAME=j2pkcs11" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2pkcs11, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +BUILD_LIBRARIES += $(BUILD_LIBJ2PKCS11) + +########################################################################################## + +ifeq ($(ENABLE_INTREE_EC), yes) + + BUILD_LIBSUNEC_FLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/security/ec \ + -I$(JDK_TOPDIR)/src/share/native/sun/security/ec/impl + + # + # On sol-sparc...all libraries are compiled with -xregs=no%appl + # (set in CFLAGS_REQUIRED_sparc) + # + # except!!! libsunec.so + # + ECC_JNI_SOLSPARC_FILTER := + ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) + ECC_JNI_SOLSPARC_FILTER := -xregs=no%appl + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBSUNEC, \ + LIBRARY := sunec, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/security/ec \ + $(JDK_TOPDIR)/src/share/native/sun/security/ec/impl, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(filter-out $(ECC_JNI_SOLSPARC_FILTER), $(CFLAGS_JDKLIB)) \ + $(BUILD_LIBSUNEC_FLAGS) \ + -DMP_API_COMPATIBLE -DNSS_ECC_MORE_THAN_SUITE_B, \ + CXXFLAGS := $(filter-out $(ECC_JNI_SOLSPARC_FILTER), $(CXXFLAGS_JDKLIB)) \ + $(BUILD_LIBSUNEC_FLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libsunec/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \ + LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(LIBCXX), \ + LDFLAGS_SUFFIX_linux := -lc, \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=sunec.dll" \ + -D "JDK_INTERNAL_NAME=sunec" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunec, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBSUNEC) +endif + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifndef OPENJDK + + $(eval $(call SetupNativeCompilation,BUILD_LIBJ2UCRYPTO, \ + LIBRARY := j2ucrypto, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/closed/solaris/native/com/oracle/security/ucrypto, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/closed/solaris/native/com/oracle/security/ucrypto, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libj2ucrypto/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB), \ + LDFLAGS_SUFFIX := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2ucrypto, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBJ2UCRYPTO) + + endif +endif diff --git a/jdk/makefiles/lib/ServiceabilityLibraries.gmk b/jdk/makefiles/lib/ServiceabilityLibraries.gmk new file mode 100644 index 00000000000..0cc5ad96a88 --- /dev/null +++ b/jdk/makefiles/lib/ServiceabilityLibraries.gmk @@ -0,0 +1,431 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +LIBATTACH_EXCLUDE_FILES := +ifneq ($(OPENJDK_TARGET_OS), solaris) + LIBATTACH_EXCLUDE_FILES += SolarisVirtualMachine.c +endif +ifneq ($(OPENJDK_TARGET_OS), linux) + LIBATTACH_EXCLUDE_FILES += LinuxVirtualMachine.c +endif +ifneq ($(OPENJDK_TARGET_OS), macosx) + LIBATTACH_EXCLUDE_FILES += BsdVirtualMachine.c +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \ + LIBRARY := attach, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/tools/attach, \ + EXCLUDE_FILES := $(LIBATTACH_EXCLUDE_FILES), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB), \ + CFLAGS_windows := /Gy, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=attach.dll" \ + -D "JDK_INTERNAL_NAME=attach" \ + -D "JDK_FTYPE=0x2L", \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_solaris := -ldoor, \ + LDFLAGS_windows := /ORDER:@$(JDK_TOPDIR)/makefiles/mapfiles/libattach/reorder-windows-$(OPENJDK_TARGET_CPU), \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib psapi.lib, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libattach, \ + DEBUG_SYMBOLS := true)) + +$(BUILD_LIBATTACH): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBATTACH) + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBDT_SOCKET, \ + LIBRARY := dt_socket, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/transport/socket \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/socket, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \ + -I$(INCLUDEDIR) -I$(JDK_OUTPUTDIR)/include/$(OPENJDK_TARGET_OS) \ + -I$(JDK_TOPDIR)/src/share/transport/socket \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/socket \ + -I$(JDK_TOPDIR)/src/share/back/export \ + -I$(JDK_TOPDIR)/src/share/back, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libdt_socket/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_linux := -lpthread, \ + LDFLAGS_SUFFIX_solaris := -lnsl -lsocket -lc, \ + LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX) -export:jdwpTransport_OnLoad ws2_32.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=dt_socket.dll" \ + -D "JDK_INTERNAL_NAME=dt_socket" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libdt_socket, \ + DEBUG_SYMBOLS := true)) + +$(BUILD_LIBDT_SOCKET): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBDT_SOCKET) + +########################################################################################## + +ifeq ($(OPENJDK_TARGET_OS), windows) + + $(eval $(call SetupNativeCompilation,BUILD_LIBDT_SHMEM, \ + LIBRARY := dt_shmem, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/com/sun/tools/jdi \ + $(JDK_TOPDIR)/src/share/transport/shmem \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/shmem, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \ + -I$(INCLUDEDIR) -I$(JDK_OUTPUTDIR)/include/$(OPENJDK_TARGET_OS) \ + -I$(JDK_TOPDIR)/src/share/transport/shmem \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/transport/shmem \ + -I$(JDK_TOPDIR)/src/share/back/export, \ + LDFLAGS := $(LDFLAGS_JDKLIB), \ + LDFLAGS_windows := -export:jdwpTransport_OnLoad, \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=dt_shmem.dll" \ + -D "JDK_INTERNAL_NAME=dt_shmem" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libdt_shmem, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBDT_SHMEM) + +endif # OPENJDK_TARGET_OS + +########################################################################################## + +# JDWP_LOGGING causes log messages to be compiled into the library. +$(eval $(call SetupNativeCompilation,BUILD_LIBJDWP, \ + LIBRARY := jdwp, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/back $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/back, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) -DJDWP_LOGGING \ + -I$(JDK_TOPDIR)/src/share/transport/export \ + -I$(JDK_TOPDIR)/src/share/back/export \ + -I$(JDK_TOPDIR)/src/share/npt \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \ + -I$(JDK_TOPDIR)/src/share/back \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/back \ + -I$(JDK_OUTPUTDIR)/gensrc_jdwp_headers, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjdwp/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_linux := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := $(LIBDL) -lc, \ + LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jdwp.dll" \ + -D "JDK_INTERNAL_NAME=jdwp" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjdwp, \ + DEBUG_SYMBOLS := true)) + +$(BUILD_LIBJDWP): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBJDWP) + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBJSDT, \ + LIBRARY := jsdt, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/native/sun/tracing/dtrace \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/tracing/dtrace, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/native/sun/tracing/dtrace, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjsdt/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_linux := $(LIBDL), \ + LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX) $(LIBDL), \ + LDFLAGS_SUFFIX_macosx := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jsdt.dll" \ + -D "JDK_INTERNAL_NAME=jsdt" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsdt, \ + DEBUG_SYMBOLS := true)) + +$(BUILD_LIBJSDT): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBJSDT) + +########################################################################################## + +LIBINSTRUMENT_SRC := $(JDK_TOPDIR)/src/share/instrument \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/instrument + +LIBINSTRUMENT_FILES := \ + EncodingSupport.c \ + EncodingSupport_md.c \ + FileSystemSupport_md.c \ + InstrumentationImplNativeMethods.c \ + InvocationAdapter.c \ + JarFacade.c \ + JPLISAgent.c \ + JPLISAssert.c \ + JavaExceptions.c \ + PathCharsValidator.c \ + Reentrancy.c \ + Utilities.c \ + canonicalize_md.c + +LIBINSTRUMENT_DIR := $(JDK_OUTPUTDIR)/objs/libinstrument +LIBINSTRUMENT_CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/instrument \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/instrument \ + -I$(JDK_TOPDIR)/src/share/bin + +LIBINSTRUMENT_LDFLAGS := +LIBINSTRUMENT_LDFLAGS_SUFFIX := + +ifeq ($(OPENJDK_TARGET_OS), windows) + LIBINSTRUMENT_LDFLAGS += $(JDK_OUTPUTDIR)/objs/jli_static.lib $(WIN_JAVA_LIB) \ + -export:Agent_OnAttach advapi32.lib + # Statically link the C runtime so that there are not dependencies on modules + # not on the search patch when invoked from the Windows system directory + # (or elsewhere). + LIBINSTRUMENT_CFLAGS := $(filter-out -MD, $(LIBINSTRUMENT_CFLAGS)) + # equivalent of strcasecmp is stricmp on Windows + LIBINSTRUMENT_CFLAGS += -Dstrcasecmp=stricmp +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBINSTRUMENT, \ + LIBRARY := instrument, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBINSTRUMENT_SRC), \ + INCLUDE_FILES := $(LIBINSTRUMENT_FILES), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(LIBINSTRUMENT_CFLAGS), \ + CFLAGS_debug := -DJPLIS_LOGGING, \ + CFLAGS_release := -DNO_JPLIS_LOGGING, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libinstrument/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(LIBINSTRUMENT_LDFLAGS), \ + LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/jli), \ + LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/jli), \ + LDFLAGS_macosx := -Xlinker -all_load $(JDK_OUTPUTDIR)/objs/libjli_static.a \ + -framework Cocoa -framework Security -framework ApplicationServices, \ + LDFLAGS_SUFFIX := $(LIBINSTRUMENT_LDFLAGS_SUFFIX), \ + LDFLAGS_SUFFIX_macosx := -liconv $(LIBZ), \ + LDFLAGS_SUFFIX_solaris := $(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL) -lc, \ + LDFLAGS_SUFFIX_linux := $(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL), \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=instrument.dll" \ + -D "JDK_INTERNAL_NAME=instrument" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(LIBINSTRUMENT_DIR), \ + DEBUG_SYMBOLS := true)) + +ifneq (, $(findstring $(OPENJDK_TARGET_OS), macosx windows)) + $(BUILD_LIBINSTRUMENT): $(JDK_OUTPUTDIR)/objs/$(LIBRARY_PREFIX)jli_static$(STATIC_LIBRARY_SUFFIX) +else + $(BUILD_LIBINSTRUMENT): $(INSTALL_LIBRARIES_HERE)/jli/$(LIBRARY_PREFIX)jli$(SHARED_LIBRARY_SUFFIX) +endif +$(BUILD_LIBINSTRUMENT): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBINSTRUMENT) + +########################################################################################## + +BUILD_LIBMANAGEMENT_SRC := $(JDK_TOPDIR)/src/share/native/sun/management \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/management \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/com/sun/management + +BUILD_LIBMANAGEMENT_EXCLUDES := + +BUILD_LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/management + +ifneq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBMANAGEMENT_EXCLUDES += OperatingSystem_md.c +else + BUILD_LIBMANAGEMENT_EXCLUDES += UnixOperatingSystem_md.c +endif + +ifneq ($(OPENJDK_TARGET_OS), solaris) + BUILD_LIBMANAGEMENT_EXCLUDES += SolarisOperatingSystem.c +endif + +ifneq ($(OPENJDK_TARGET_OS), linux) + BUILD_LIBMANAGEMENT_EXCLUDES += LinuxOperatingSystem.c +endif + +ifneq ($(OPENJDK_TARGET_OS), macosx) + BUILD_LIBMANAGEMENT_EXCLUDES += MacosxOperatingSystem.c +endif + +LIBMANAGEMENT_OPTIMIZATION := HIGH +ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) + ifeq ($(ENABLE_DEBUG_SYMBOLS), true) + LIBMANAGEMENT_OPTIMIZATION := LOW + endif +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \ + LIBRARY := management, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(BUILD_LIBMANAGEMENT_SRC), \ + EXCLUDE_FILES := $(BUILD_LIBMANAGEMENT_EXCLUDES), \ + LANG := C, \ + OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \ + CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBMANAGEMENT_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libmanagement/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_solaris := -lkstat, \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=management.dll" \ + -D "JDK_INTERNAL_NAME=management" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libmanagement, \ + DEBUG_SYMBOLS := true)) + +$(BUILD_LIBMANAGEMENT): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBMANAGEMENT) + +########################################################################################## + +BUILD_LIBHPROF_SRC := $(JDK_TOPDIR)/src/share/demo/jvmti/hprof $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/demo/jvmti/hprof +BUILD_LIBHPROF_CFLAGS := -I$(JDK_TOPDIR)/src/share/demo/jvmti/hprof \ + -I$(JDK_TOPDIR)/src/share/npt \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \ + -I$(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo + +BUILD_LIBHPROF_LDFLAGS := + +LIBHPROF_OPTIMIZATION := HIGHEST +ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) + ifeq ($(ENABLE_DEBUG_SYMBOLS), true) + LIBHPROF_OPTIMIZATION := LOW + endif +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBHPROF, \ + LIBRARY := hprof, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(BUILD_LIBHPROF_SRC), \ + LANG := C, \ + OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(BUILD_LIBHPROF_CFLAGS), \ + CFLAGS_debug := -DHPROF_LOGGING, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libhprof/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_windows := wsock32.lib winmm.lib advapi32.lib, \ + LDFLAGS_SUFFIX_linux := $(LIBDL), \ + LDFLAGS_SUFFIX_macosx := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -lsocket -lnsl $(LIBDL) -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=hprof.dll" \ + -D "JDK_INTERNAL_NAME=hprof" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libhprof_jvmti, \ + DEBUG_SYMBOLS := true)) + +BUILD_LIBRARIES += $(BUILD_LIBHPROF) + +########################################################################################## + +$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA_CRW_DEMO, \ + LIBRARY := java_crw_demo, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjava_crw_demo/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=java_crw_demo.dll" \ + -D "JDK_INTERNAL_NAME=java_crw_demo" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjava_crw_demo, \ + DEBUG_SYMBOLS := true)) + +BUILD_LIBRARIES += $(BUILD_LIBJAVA_CRW_DEMO) + +########################################################################################## + +ifndef OPENJDK + ifeq ($(ENABLE_JFR), true) + + $(eval $(call SetupNativeCompilation,BUILD_LIBJFR, \ + LIBRARY := jfr, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(JDK_TOPDIR)/src/closed/share/native/oracle/jfr, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(JDK_TOPDIR)/src/closed/share/javavm/export, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjfr/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jfr.dll" \ + -D "JDK_INTERNAL_NAME=jfr" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjfr, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + BUILD_LIBRARIES += $(BUILD_LIBJFR) + + endif +endif diff --git a/jdk/makefiles/lib/SoundLibraries.gmk b/jdk/makefiles/lib/SoundLibraries.gmk new file mode 100644 index 00000000000..dc507ab58cf --- /dev/null +++ b/jdk/makefiles/lib/SoundLibraries.gmk @@ -0,0 +1,237 @@ +# +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +LIBJSOUND_SRC_DIRS := \ + $(JDK_TOPDIR)/src/share/native/com/sun/media/sound \ + $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/com/sun/media/sound + +LIBJSOUND_SRC_FILES := Utilities.c Platform.c + +LIBJSOUND_LANG := C +LIBJSOUND_CFLAGS := $(foreach dir, $(LIBJSOUND_SRC_DIRS), -I$(dir)) + +EXTRA_SOUND_JNI_LIBS := + +LIBJSOUND_MIDIFILES := \ + MidiInDevice.c \ + MidiInDeviceProvider.c \ + MidiOutDevice.c \ + MidiOutDeviceProvider.c \ + PlatformMidi.c + +# files needed for ports +LIBJSOUND_PORTFILES := \ + PortMixerProvider.c \ + PortMixer.c + +# files needed for direct audio +LIBJSOUND_DAUDIOFILES := \ + DirectAudioDeviceProvider.c \ + DirectAudioDevice.c + +ifeq ($(OPENJDK_TARGET_OS), windows) + EXTRA_SOUND_JNI_LIBS += jsoundds + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS \ + -DUSE_PLATFORM_MIDI_OUT=TRUE \ + -DUSE_PLATFORM_MIDI_IN=TRUE \ + -DUSE_PORTS=TRUE + LIBJSOUND_SRC_FILES += \ + PLATFORM_API_WinOS_MidiIn.cpp \ + PLATFORM_API_WinOS_MidiOut.c \ + PLATFORM_API_WinOS_Util.c \ + PLATFORM_API_WinOS_Ports.c + LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) + LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) +endif # OPENJDK_TARGET_OS windows + +ifeq ($(OPENJDK_TARGET_OS), linux) + EXTRA_SOUND_JNI_LIBS += jsoundalsa + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_LINUX +endif # OPENJDK_TARGET_OS linux + +ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBJSOUND_LANG := C++ + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX \ + -DUSE_PORTS=TRUE \ + -DUSE_DAUDIO=TRUE \ + -DUSE_PLATFORM_MIDI_OUT=TRUE \ + -DUSE_PLATFORM_MIDI_IN=TRUE + LIBJSOUND_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/com/sun/media/sound + LIBJSOUND_SRC_FILES += \ + PLATFORM_API_MacOSX_Utils.cpp \ + PLATFORM_API_MacOSX_PCM.cpp \ + PLATFORM_API_MacOSX_Ports.cpp \ + PLATFORM_API_MacOSX_MidiIn.c \ + PLATFORM_API_MacOSX_MidiOut.c \ + PLATFORM_API_MacOSX_MidiUtils.c + LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) + LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) + LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES) +endif # OPENJDK_TARGET_OS macosx + +ifeq ($(OPENJDK_TARGET_OS), solaris) + LIBJSOUND_CFLAGS += -DX_PLATFORM=X_SOLARIS \ + -DUSE_PORTS=TRUE \ + -DUSE_DAUDIO=TRUE + LIBJSOUND_SRC_FILES += \ + PLATFORM_API_SolarisOS_Utils.c \ + PLATFORM_API_SolarisOS_Ports.c \ + PLATFORM_API_SolarisOS_PCM.c + LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES) + LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES) + LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES) +endif # OPENJDK_TARGET_OS solaris + + +ifeq ($(JVM_VARIANT_ZERO), true) + LIBJSOUND_CFLAGS += -DX_ARCH=X_ZERO +else + ifeq ($(OPENJDK_TARGET_CPU), x86) + LIBJSOUND_CFLAGS += -DX_ARCH=X_I586 + endif + + ifeq ($(OPENJDK_TARGET_CPU), sparc) + LIBJSOUND_CFLAGS += -DX_ARCH=X_SPARC + endif + + ifeq ($(OPENJDK_TARGET_CPU), sparcv9) + LIBJSOUND_CFLAGS += -DX_ARCH=X_SPARCV9 + endif + + ifeq ($(OPENJDK_TARGET_CPU), x86_64) + LIBJSOUND_CFLAGS += -DX_ARCH=X_AMD64 + endif + + ifeq ($(OPENJDK_TARGET_CPU), arm) + LIBJSOUND_CFLAGS += -DX_ARCH=X_ARM + endif + + ifeq ($(OPENJDK_TARGET_CPU), ppc) + LIBJSOUND_CFLAGS += -DX_ARCH=X_PPC + endif +endif + +LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"' + +$(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \ + LIBRARY := jsound, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBJSOUND_SRC_DIRS), \ + INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \ + LANG := $(LIBJSOUND_LANG), \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(LIBJSOUND_CFLAGS), \ + CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBJSOUND_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjsound/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_macosx := -framework CoreAudio -framework CoreFoundation \ + -framework CoreServices -framework AudioUnit $(LIBCXX) \ + -framework CoreMIDI -framework AudioToolbox, \ + LDFLAGS_windows := $(WIN_JAVA_LIB) advapi32.lib winmm.lib, \ + LDFLAGS_SUFFIX_posix := -ljava -ljvm, \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jsound.dll" \ + -D "JDK_INTERNAL_NAME=jsound" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsound, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + +$(BUILD_LIBJSOUND): $(BUILD_LIBJAVA) + +BUILD_LIBRARIES += $(BUILD_LIBJSOUND) + +########################################################################################## + +ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), ) + + $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDALSA, \ + LIBRARY := jsoundalsa, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBJSOUND_SRC_DIRS), \ + INCLUDE_FILES := Utilities.c $(LIBJSOUND_MIDIFILES) $(LIBJSOUND_PORTFILES) \ + $(LIBJSOUND_DAUDIOFILES) \ + PLATFORM_API_LinuxOS_ALSA_CommonUtils.c \ + PLATFORM_API_LinuxOS_ALSA_PCM.c \ + PLATFORM_API_LinuxOS_ALSA_PCMUtils.c \ + PLATFORM_API_LinuxOS_ALSA_MidiIn.c \ + PLATFORM_API_LinuxOS_ALSA_MidiOut.c \ + PLATFORM_API_LinuxOS_ALSA_MidiUtils.c \ + PLATFORM_API_LinuxOS_ALSA_Ports.c, \ + LANG := C, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) $(ALSA_CFLAGS) \ + $(LIBJSOUND_CFLAGS) \ + -DUSE_DAUDIO=TRUE \ + -DUSE_PORTS=TRUE \ + -DUSE_PLATFORM_MIDI_OUT=TRUE \ + -DUSE_PLATFORM_MIDI_IN=TRUE, \ + MAPFILE := $(JDK_TOPDIR)/makefiles/mapfiles/libjsoundalsa/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(ALSA_LIBS) -ljava -ljvm, \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsoundalsa, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBJSOUNDALSA): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBJSOUNDALSA) + +endif + +########################################################################################## + +ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), ) + + $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS, \ + LIBRARY := jsoundds, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBJSOUND_SRC_DIRS), \ + INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ + PLATFORM_API_WinOS_DirectSound.cpp, \ + LANG := C++, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(LIBJSOUND_CFLAGS) \ + -DUSE_DAUDIO=TRUE, \ + LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=jsoundds.dll" \ + -D "JDK_INTERNAL_NAME=jsoundds" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsoundds, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + $(BUILD_LIBJSOUNDDS): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBJSOUNDDS) + +endif From b8aff04aa02244c252c7ab7e1820c7a20a79d2d9 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Wed, 16 Oct 2013 16:33:04 -0400 Subject: [PATCH 110/152] 8026286: Improper locking of annotation queues causes assertion failures 8026063: Calls to annotate.flush() cause incorrect type annotations to be generated Fix locking in ClassReader.java Reviewed-by: jfranck --- .../sun/tools/javac/code/TypeAnnotations.java | 13 +---- .../com/sun/tools/javac/comp/Annotate.java | 6 ++ .../com/sun/tools/javac/jvm/ClassReader.java | 11 ++-- .../TestAnonInnerInstance1.java | 57 +++++++++++++++++++ .../typeAnnotations/classfile/T8008762.java | 1 - 5 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 909ec875d79..36da3077f05 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -97,7 +97,6 @@ public class TypeAnnotations { final Symtab syms; final Annotate annotate; final Attr attr; - private final boolean typeAnnoAsserts; protected TypeAnnotations(Context context) { context.put(typeAnnosKey, this); @@ -107,7 +106,6 @@ public class TypeAnnotations { annotate = Annotate.instance(context); attr = Attr.instance(context); Options options = Options.instance(context); - typeAnnoAsserts = options.isSet("TypeAnnotationAsserts"); } /** @@ -1042,11 +1040,7 @@ public class TypeAnnotations { @Override public void visitMethodDef(final JCMethodDecl tree) { if (tree.sym == null) { - if (typeAnnoAsserts) { - Assert.error("Visiting tree node before memberEnter"); - } else { - return; - } + Assert.error("Visiting tree node before memberEnter"); } if (sigOnly) { if (!tree.mods.annotations.isEmpty()) { @@ -1150,10 +1144,7 @@ public class TypeAnnotations { // Nothing to do for separateAnnotationsKinds if // there are no annotations of either kind. } else if (tree.sym == null) { - if (typeAnnoAsserts) { - Assert.error("Visiting tree node before memberEnter"); - } - // Something is wrong already. Quietly ignore. + Assert.error("Visiting tree node before memberEnter"); } else if (tree.sym.getKind() == ElementKind.PARAMETER) { // Parameters are handled in visitMethodDef or visitLambda. } else if (tree.sym.getKind() == ElementKind.FIELD) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index 5fe4d3ba121..bc0903fd2c3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -129,6 +129,12 @@ public class Annotate { flush(); } + /** Variant which allows for a delayed flush of annotations. + * Needed by ClassReader */ + public void enterDoneWithoutFlush() { + enterCount--; + } + public void flush() { if (enterCount != 0) return; enterCount++; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index c172bb396d5..8dcf059f126 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -2405,8 +2405,6 @@ public class ClassReader { return c; } - private boolean suppressFlush = false; - /** Completion for classes to be loaded. Before a class is loaded * we make sure its enclosing class (if any) is loaded. */ @@ -2414,13 +2412,14 @@ public class ClassReader { if (sym.kind == TYP) { ClassSymbol c = (ClassSymbol)sym; c.members_field = new Scope.ErrorScope(c); // make sure it's always defined - boolean saveSuppressFlush = suppressFlush; - suppressFlush = true; + annotate.enterStart(); try { completeOwners(c.owner); completeEnclosing(c); } finally { - suppressFlush = saveSuppressFlush; + // The flush needs to happen only after annotations + // are filled in. + annotate.enterDoneWithoutFlush(); } fillIn(c); } else if (sym.kind == PCK) { @@ -2431,7 +2430,7 @@ public class ClassReader { throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); } } - if (!filling && !suppressFlush) + if (!filling) annotate.flush(); // finish attaching annotations } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java b/langtools/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java new file mode 100644 index 00000000000..190f8b10028 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8026286 + * @summary This test previously forced an assertion to fail, due to + * TypeAnnotationPosition visiting a tree node prior to + * memberEnter. + * @compile TestAnonInnerInstance1.java + */ + +import java.lang.annotation.*; +import static java.lang.annotation.RetentionPolicy.*; +import static java.lang.annotation.ElementType.*; +import java.util.List; + +class TestAnonInnerInstance1 { + Object mtest(TestAnonInnerInstance1 t){ return null; } + Object mmtest(TestAnonInnerInstance1 t){ return null; } + + public void test() { + + mtest(new TestAnonInnerInstance1() { + class InnerAnon { // Test1$1$InnerAnon.class + @A @B @C @D String ia_m1(){ return null; }; + } + //If this is commented out, annotations are attributed correctly + InnerAnon IA = new InnerAnon< String>(); + }); + } +} + +@Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface A { } +@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @interface B { } +@Retention(CLASS) @Target({TYPE_USE,FIELD}) @interface C { } +@Retention(CLASS) @Target({TYPE_USE,METHOD}) @interface D { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java index 046fc0abe64..4b37b0598f6 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java @@ -24,7 +24,6 @@ /* * @test * @bug 8008762 - * @ignore 8013409: test failures for type annotations * @summary Type annotation on inner class in anonymous class * shows up as regular annotation */ From c0555a7232e2bd3fc5fa5c8c94f032a44c1c175d Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Wed, 16 Oct 2013 23:31:16 -0700 Subject: [PATCH 111/152] 8026762: jdk8-tl builds windows builds failing in corba - javac: no source files Reviewed-by: katleman, dholmes --- corba/makefiles/BuildCorba.gmk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/corba/makefiles/BuildCorba.gmk b/corba/makefiles/BuildCorba.gmk index 1e1ab5c1c7e..b55a8321852 100644 --- a/corba/makefiles/BuildCorba.gmk +++ b/corba/makefiles/BuildCorba.gmk @@ -45,8 +45,9 @@ DISABLE_CORBA_WARNINGS:=-Xlint:all,-deprecation,-unchecked,-serial,-fallthrough, $(eval $(call SetupJavaCompiler,GENERATE_OLDBYTECODE,\ JVM:=$(JAVA),\ JAVAC:=$(NEW_JAVAC),\ - FLAGS := $(BOOT_JDK_SOURCETARGET) -bootclasspath $(BOOT_RTJAR)$(PATH_SEP)$(BOOT_TOOLSJAR) \ - $(DISABLE_CORBA_WARNINGS), \ + FLAGS := $(BOOT_JDK_SOURCETARGET) \ + -bootclasspath "$(BOOT_RTJAR)$(PATH_SEP)$(BOOT_TOOLSJAR)" \ + $(DISABLE_CORBA_WARNINGS), \ SERVER_DIR:=$(SJAVAC_SERVER_DIR),\ SERVER_JVM:=$(SJAVAC_SERVER_JAVA))) From 7bf2a9861b38b5e01d51af29b0e36f3c220f5fbe Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 17 Oct 2013 08:41:35 +0200 Subject: [PATCH 112/152] 8026707: JDK-8026391 broke the optimized build target Reviewed-by: mgerdin, coleenp --- hotspot/src/share/vm/memory/metachunk.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/memory/metachunk.hpp b/hotspot/src/share/vm/memory/metachunk.hpp index 5ea8e235de6..3bd4d15bca8 100644 --- a/hotspot/src/share/vm/memory/metachunk.hpp +++ b/hotspot/src/share/vm/memory/metachunk.hpp @@ -139,11 +139,12 @@ class Metachunk : public Metabase { size_t free_word_size() const; #ifdef ASSERT - void mangle(); bool is_tagged_free() { return _is_tagged_free; } void set_is_tagged_free(bool v) { _is_tagged_free = v; } #endif + NOT_PRODUCT(void mangle();) + void print_on(outputStream* st) const; void verify(); }; From 79199b95bca40b3cfdb05b5c0ba23ca237acd104 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 17 Oct 2013 08:42:41 +0200 Subject: [PATCH 113/152] 8026715: Remove the MetaDataDeallocateALot develop flag Reviewed-by: coleenp, mgerdin --- hotspot/src/share/vm/memory/metaspace.cpp | 114 +--------------------- hotspot/src/share/vm/runtime/globals.hpp | 7 -- 2 files changed, 1 insertion(+), 120 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 13c88adb0b2..9b321de4c44 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -52,9 +52,6 @@ typedef BinaryTreeDictionary ChunkTreeDictionary; // Set this constant to enable slow integrity checking of the free chunk lists const bool metaspace_slow_verify = false; -// Parameters for stress mode testing -const uint metadata_deallocate_a_lot_block = 10; -const uint metadata_deallocate_a_lock_chunk = 3; size_t const allocation_from_dictionary_limit = 4 * K; MetaWord* last_allocated = 0; @@ -149,7 +146,6 @@ class ChunkManager : public CHeapObj { // add or delete (return) a chunk to the global freelist. Metachunk* chunk_freelist_allocate(size_t word_size); - void chunk_freelist_deallocate(Metachunk* chunk); // Map a size to a list index assuming that there are lists // for special, small, medium, and humongous chunks. @@ -183,9 +179,7 @@ class ChunkManager : public CHeapObj { // Returns the list for the given chunk word size. ChunkList* find_free_chunks_list(size_t word_size); - // Add and remove from a list by size. Selects - // list based on size of chunk. - void free_chunks_put(Metachunk* chuck); + // Remove from a list by size. Selects list based on size of chunk. Metachunk* free_chunks_get(size_t chunk_word_size); // Debug support @@ -533,44 +527,16 @@ class VirtualSpaceList : public CHeapObj { class Metadebug : AllStatic { // Debugging support for Metaspaces - static int _deallocate_block_a_lot_count; - static int _deallocate_chunk_a_lot_count; static int _allocation_fail_alot_count; public: - static int deallocate_block_a_lot_count() { - return _deallocate_block_a_lot_count; - } - static void set_deallocate_block_a_lot_count(int v) { - _deallocate_block_a_lot_count = v; - } - static void inc_deallocate_block_a_lot_count() { - _deallocate_block_a_lot_count++; - } - static int deallocate_chunk_a_lot_count() { - return _deallocate_chunk_a_lot_count; - } - static void reset_deallocate_chunk_a_lot_count() { - _deallocate_chunk_a_lot_count = 1; - } - static void inc_deallocate_chunk_a_lot_count() { - _deallocate_chunk_a_lot_count++; - } static void init_allocation_fail_alot_count(); #ifdef ASSERT static bool test_metadata_failure(); #endif - - static void deallocate_chunk_a_lot(SpaceManager* sm, - size_t chunk_word_size); - static void deallocate_block_a_lot(SpaceManager* sm, - size_t chunk_word_size); - }; -int Metadebug::_deallocate_block_a_lot_count = 0; -int Metadebug::_deallocate_chunk_a_lot_count = 0; int Metadebug::_allocation_fail_alot_count = 0; // SpaceManager - used by Metaspace to handle allocations @@ -1534,54 +1500,6 @@ void MetaspaceGC::compute_new_size() { // Metadebug methods -void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm, - size_t chunk_word_size){ -#ifdef ASSERT - VirtualSpaceList* vsl = sm->vs_list(); - if (MetaDataDeallocateALot && - Metadebug::deallocate_chunk_a_lot_count() % MetaDataDeallocateALotInterval == 0 ) { - Metadebug::reset_deallocate_chunk_a_lot_count(); - for (uint i = 0; i < metadata_deallocate_a_lock_chunk; i++) { - Metachunk* dummy_chunk = vsl->current_virtual_space()->take_from_committed(chunk_word_size); - if (dummy_chunk == NULL) { - break; - } - sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); - - if (TraceMetadataChunkAllocation && Verbose) { - gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", - sm->sum_count_in_chunks_in_use()); - dummy_chunk->print_on(gclog_or_tty); - gclog_or_tty->print_cr(" Free chunks total %d count %d", - sm->chunk_manager()->free_chunks_total_words(), - sm->chunk_manager()->free_chunks_count()); - } - } - } else { - Metadebug::inc_deallocate_chunk_a_lot_count(); - } -#endif -} - -void Metadebug::deallocate_block_a_lot(SpaceManager* sm, - size_t raw_word_size){ -#ifdef ASSERT - if (MetaDataDeallocateALot && - Metadebug::deallocate_block_a_lot_count() % MetaDataDeallocateALotInterval == 0 ) { - Metadebug::set_deallocate_block_a_lot_count(0); - for (uint i = 0; i < metadata_deallocate_a_lot_block; i++) { - MetaWord* dummy_block = sm->allocate_work(raw_word_size); - if (dummy_block == 0) { - break; - } - sm->deallocate(dummy_block, raw_word_size); - } - } else { - Metadebug::inc_deallocate_block_a_lot_count(); - } -#endif -} - void Metadebug::init_allocation_fail_alot_count() { if (MetadataAllocationFailALot) { _allocation_fail_alot_count = @@ -1725,31 +1643,6 @@ ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) { return free_chunks(index); } -void ChunkManager::free_chunks_put(Metachunk* chunk) { - assert_lock_strong(SpaceManager::expand_lock()); - ChunkList* free_list = find_free_chunks_list(chunk->word_size()); - chunk->set_next(free_list->head()); - free_list->set_head(chunk); - // chunk is being returned to the chunk free list - inc_free_chunks_total(chunk->word_size()); - slow_locked_verify(); -} - -void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { - // The deallocation of a chunk originates in the freelist - // manangement code for a Metaspace and does not hold the - // lock. - assert(chunk != NULL, "Deallocating NULL"); - assert_lock_strong(SpaceManager::expand_lock()); - slow_locked_verify(); - if (TraceMetadataChunkAllocation) { - gclog_or_tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " - PTR_FORMAT " size " SIZE_FORMAT, - chunk, chunk->word_size()); - } - free_chunks_put(chunk); -} - Metachunk* ChunkManager::free_chunks_get(size_t word_size) { assert_lock_strong(SpaceManager::expand_lock()); @@ -2069,10 +1962,6 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) { size_t grow_chunks_by_words = calc_chunk_size(word_size); Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); - if (next != NULL) { - Metadebug::deallocate_chunk_a_lot(this, grow_chunks_by_words); - } - MetaWord* mem = NULL; // If a chunk was available, add it to the in-use chunk list @@ -2417,7 +2306,6 @@ MetaWord* SpaceManager::allocate(size_t word_size) { if (p == NULL) { p = allocate_work(raw_word_size); } - Metadebug::deallocate_block_a_lot(this, raw_word_size); return p; } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 5d395732681..8495804e6e2 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1979,13 +1979,6 @@ class CommandLineFlags { develop(uintx, MetadataAllocationFailALotInterval, 1000, \ "Metadata allocation failure a lot interval") \ \ - develop(bool, MetaDataDeallocateALot, false, \ - "Deallocation bunches of metadata at intervals controlled by " \ - "MetaDataAllocateALotInterval") \ - \ - develop(uintx, MetaDataDeallocateALotInterval, 100, \ - "Metadata deallocation alot interval") \ - \ develop(bool, TraceMetadataChunkAllocation, false, \ "Trace chunk metadata allocations") \ \ From 7c6e4696ab8c711e9dc187308c446401c5409e43 Mon Sep 17 00:00:00 2001 From: Matherey Nunez Date: Thu, 17 Oct 2013 13:27:36 +0200 Subject: [PATCH 114/152] 8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final Reviewed-by: jjg, jfranck --- .../MethodParameters/AnnotationTest.java | 2 +- .../javac/MethodParameters/AnnotationTest.out | 10 +++ .../MethodParameters/AnonymousClass.java | 2 +- .../javac/MethodParameters/AnonymousClass.out | 80 +++++++++++++++++++ .../MethodParameters/ClassFileVisitor.java | 63 +++++++++++---- .../javac/MethodParameters/Constructors.java | 2 +- .../javac/MethodParameters/Constructors.out | 5 ++ .../javac/MethodParameters/EnumTest.java | 2 +- .../tools/javac/MethodParameters/EnumTest.out | 7 ++ .../MethodParameters/InstanceMethods.java | 2 +- .../MethodParameters/InstanceMethods.out | 11 +++ .../javac/MethodParameters/LambdaTest.java | 2 +- .../javac/MethodParameters/LambdaTest.out | 7 ++ .../MethodParameters/LocalClassTest.java | 2 +- .../javac/MethodParameters/LocalClassTest.out | 12 +++ .../MethodParameters/MemberClassTest.java | 2 +- .../MethodParameters/MemberClassTest.out | 33 ++++++++ .../MethodParameters/ReflectionVisitor.java | 59 +++++++++++--- .../javac/MethodParameters/StaticMethods.java | 2 +- .../javac/MethodParameters/StaticMethods.out | 11 +++ .../tools/javac/MethodParameters/Tester.java | 68 +++++++++++++--- .../MethodParameters/UncommonParamNames.java | 2 +- .../MethodParameters/UncommonParamNames.out | 17 ++++ 23 files changed, 352 insertions(+), 51 deletions(-) create mode 100644 langtools/test/tools/javac/MethodParameters/AnnotationTest.out create mode 100644 langtools/test/tools/javac/MethodParameters/AnonymousClass.out create mode 100644 langtools/test/tools/javac/MethodParameters/Constructors.out create mode 100644 langtools/test/tools/javac/MethodParameters/EnumTest.out create mode 100644 langtools/test/tools/javac/MethodParameters/InstanceMethods.out create mode 100644 langtools/test/tools/javac/MethodParameters/LambdaTest.out create mode 100644 langtools/test/tools/javac/MethodParameters/LocalClassTest.out create mode 100644 langtools/test/tools/javac/MethodParameters/MemberClassTest.out create mode 100644 langtools/test/tools/javac/MethodParameters/StaticMethods.out create mode 100644 langtools/test/tools/javac/MethodParameters/UncommonParamNames.out diff --git a/langtools/test/tools/javac/MethodParameters/AnnotationTest.java b/langtools/test/tools/javac/MethodParameters/AnnotationTest.java index ca8cd520758..96eaaed4fb1 100644 --- a/langtools/test/tools/javac/MethodParameters/AnnotationTest.java +++ b/langtools/test/tools/javac/MethodParameters/AnnotationTest.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters AnnotationTest.java - * @run main Tester AnnotationTest + * @run main Tester AnnotationTest AnnotationTest.out */ import java.lang.annotation.*; diff --git a/langtools/test/tools/javac/MethodParameters/AnnotationTest.out b/langtools/test/tools/javac/MethodParameters/AnnotationTest.out new file mode 100644 index 00000000000..168cb16d568 --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/AnnotationTest.out @@ -0,0 +1,10 @@ +static interface AnnotationTest$Annos -- inner +AnnotationTest$Annos.foo() +AnnotationTest$Annos.value() +class AnnotationTest -- +AnnotationTest.(i, ji) +AnnotationTest.foo(i, ji) +static interface AnnotationTest$I -- inner +AnnotationTest$I.m(i, ji) +static interface AnnotationTest$Anno -- inner +AnnotationTest$Anno.f() \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/AnonymousClass.java b/langtools/test/tools/javac/MethodParameters/AnonymousClass.java index ee87a2051c2..7cae4871102 100644 --- a/langtools/test/tools/javac/MethodParameters/AnonymousClass.java +++ b/langtools/test/tools/javac/MethodParameters/AnonymousClass.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters AnonymousClass.java - * @run main Tester AnonymousClass + * @run main Tester AnonymousClass AnonymousClass.out */ class AnonymousClass { diff --git a/langtools/test/tools/javac/MethodParameters/AnonymousClass.out b/langtools/test/tools/javac/MethodParameters/AnonymousClass.out new file mode 100644 index 00000000000..b2f482bd2a4 --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/AnonymousClass.out @@ -0,0 +1,80 @@ +static public class AnonymousClass$Sinner -- inner +AnonymousClass$Sinner.() +AnonymousClass$Sinner.(arg, barg) +AnonymousClass$Sinner.m(s/*synthetic*/, ts/*synthetic*/)/*synthetic*/ +AnonymousClass$Sinner.m()/*synthetic*/ +AnonymousClass$Sinner.m(s, ts) +AnonymousClass$Sinner.m() +class AnonymousClass$9 -- anon +AnonymousClass$9.(final this$0/*implicit*/) +AnonymousClass$9.m()/*synthetic*/ +AnonymousClass$9.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$9.m(i, ji) +AnonymousClass$9.m() +class AnonymousClass$Inner -- inner +AnonymousClass$Inner.(final this$0/*synthetic*/) +AnonymousClass$Inner.(final this$0/*synthetic*/, arg, barg) +AnonymousClass$Inner.m(s/*synthetic*/, ts/*synthetic*/)/*synthetic*/ +AnonymousClass$Inner.m()/*synthetic*/ +AnonymousClass$Inner.m(s, ts) +AnonymousClass$Inner.m() +class AnonymousClass$3 -- anon +AnonymousClass$3.(final this$0/*implicit*/, arg, barg) +AnonymousClass$3.m()/*synthetic*/ +AnonymousClass$3.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$3.m(i, ji) +AnonymousClass$3.m() +class AnonymousClass$2 -- anon +AnonymousClass$2.(final this$0/*implicit*/) +AnonymousClass$2.m()/*synthetic*/ +AnonymousClass$2.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$2.m(i, ji) +AnonymousClass$2.m() +class AnonymousClass -- +AnonymousClass.(final a, ba) +AnonymousClass.foo(final a, ba) +class AnonymousClass$5 -- anon +AnonymousClass$5.(final this$0/*implicit*/, arg, barg) +AnonymousClass$5.m()/*synthetic*/ +AnonymousClass$5.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$5.m(i, ji) +AnonymousClass$5.m() +static interface AnonymousClass$I -- inner +AnonymousClass$I.m() +AnonymousClass$I.m(x, yx) +class AnonymousClass$10 -- anon +AnonymousClass$10.(final this$0/*implicit*/, arg, barg) +AnonymousClass$10.m()/*synthetic*/ +AnonymousClass$10.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$10.m(i, ji) +AnonymousClass$10.m() +class AnonymousClass$8 -- anon +AnonymousClass$8.(final this$0/*implicit*/, arg, barg) +AnonymousClass$8.m()/*synthetic*/ +AnonymousClass$8.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$8.m(i, ji) +AnonymousClass$8.m() +class AnonymousClass$6 -- anon +AnonymousClass$6.(final this$0/*implicit*/) +AnonymousClass$6.m()/*synthetic*/ +AnonymousClass$6.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$6.m(i, ji) +AnonymousClass$6.m() +class AnonymousClass$7 -- anon +AnonymousClass$7.(final this$0/*implicit*/) +AnonymousClass$7.m()/*synthetic*/ +AnonymousClass$7.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$7.m(i, ji) +AnonymousClass$7.m() +class AnonymousClass$4 -- anon +AnonymousClass$4.(final this$0/*implicit*/) +AnonymousClass$4.m()/*synthetic*/ +AnonymousClass$4.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$4.m(i, ji) +AnonymousClass$4.m() +class AnonymousClass$1 -- anon +AnonymousClass$1.(final this$0/*implicit*/) +AnonymousClass$1.m()/*synthetic*/ +AnonymousClass$1.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/ +AnonymousClass$1.m(i, ji) +AnonymousClass$1.m() \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java index 777a552769a..616d7f40001 100644 --- a/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java +++ b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java @@ -82,15 +82,14 @@ class ClassFileVisitor extends Tester.Visitor { * Read the class and determine some key characteristics, like if it's * an enum, or inner class, etc. */ - void visitClass(final String cname, final File cfile, final StringBuilder sb) - throws Exception { + void visitClass(final String cname, final File cfile, final StringBuilder sb) throws Exception { this.cname = cname; classFile = ClassFile.read(cfile); isEnum = classFile.access_flags.is(AccessFlags.ACC_ENUM); isInterface = classFile.access_flags.is(AccessFlags.ACC_INTERFACE); isPublic = classFile.access_flags.is(AccessFlags.ACC_PUBLIC); isInner = false; - isStatic = true; + isStatic = false; isAnon = false; Attribute attr = classFile.getAttribute("InnerClasses"); @@ -100,10 +99,11 @@ class ClassFileVisitor extends Tester.Visitor { sb.append(isStatic ? "static " : "") .append(isPublic ? "public " : "") .append(isEnum ? "enum " : isInterface ? "interface " : "class ") - .append(cname).append(" -- ") - .append(isInner? "inner " : "" ) - .append(isAnon ? "anon" : "") - .append("\n");; + .append(cname).append(" -- "); + if (isInner) { + sb.append(isAnon ? "anon" : "inner"); + } + sb.append("\n"); for (Method method : classFile.methods) { new MethodVisitor().visitMethod(method, sb); @@ -148,7 +148,9 @@ class ClassFileVisitor extends Tester.Visitor { public int mNumParams; public boolean mSynthetic; public boolean mIsConstructor; + public boolean mIsClinit; public boolean mIsBridge; + public boolean isFinal; public String prefix; void visitMethod(Method method, StringBuilder sb) throws Exception { @@ -160,9 +162,13 @@ class ClassFileVisitor extends Tester.Visitor { mNumParams = -1; // no MethodParameters attribute found mSynthetic = method.access_flags.is(AccessFlags.ACC_SYNTHETIC); mIsConstructor = mName.equals(""); + mIsClinit = mName.equals(""); prefix = cname + "." + mName + "() - "; mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE); + if (mIsClinit) { + sb = new StringBuilder(); // Discard output + } sb.append(cname).append(".").append(mName).append("("); for (Attribute a : method.attributes) { @@ -170,9 +176,18 @@ class ClassFileVisitor extends Tester.Visitor { } if (mNumParams == -1) { if (mSynthetic) { - sb.append(")!!"); + // We don't generate MethodParameters attribute for synthetic + // methods, so we are creating a parameter pattern to match + // ReflectionVisitor API output. + for (int i = 0; i < mParams; i++) { + if (i == 0) + sb.append("arg").append(i); + else + sb.append(", arg").append(i); + } + sb.append(")/*synthetic*/"); } else { - sb.append(")"); + sb.append(")"); } } sb.append("\n"); @@ -217,7 +232,7 @@ class ClassFileVisitor extends Tester.Visitor { String sep = ""; String userParam = null; for (int x = 0; x < mNumParams; x++) { - + isFinal = (mp.method_parameter_table[x].flags & AccessFlags.ACC_FINAL) != 0; // IMPL: Assume all parameters are named, something. int cpi = mp.method_parameter_table[x].name_index; if (cpi == 0) { @@ -229,6 +244,8 @@ class ClassFileVisitor extends Tester.Visitor { String param = null; try { param = classFile.constant_pool.getUTF8Value(cpi); + if (isFinal) + param = "final " + param; sb.append(sep).append(param); sep = ", "; } catch(ConstantPoolException e) { @@ -239,7 +256,7 @@ class ClassFileVisitor extends Tester.Visitor { // Check availability, flags and special names - int check = checkParam(mp, param, x, sb); + int check = checkParam(mp, param, x, sb, isFinal); if (check < 0) { return null; } @@ -253,9 +270,15 @@ class ClassFileVisitor extends Tester.Visitor { char c = userParam.charAt(0); expect = (++c) + userParam; } + if(isFinal && expect != null) + expect = "final " + expect; if (check > 0) { + if(isFinal) { + userParam = param.substring(6); + } else { userParam = param; } + } if (expect != null && !param.equals(expect)) { error(prefix + "param[" + x + "]='" + param + "' expected '" + expect + "'"); @@ -263,7 +286,7 @@ class ClassFileVisitor extends Tester.Visitor { } } if (mSynthetic) { - sb.append(")!!"); + sb.append(")/*synthetic*/"); } else { sb.append(")"); } @@ -278,7 +301,7 @@ class ClassFileVisitor extends Tester.Visitor { * explicitly declared parameter. */ int checkParam(MethodParameters_attribute mp, String param, int index, - StringBuilder sb) { + StringBuilder sb, boolean isFinal) { boolean synthetic = (mp.method_parameter_table[index].flags & AccessFlags.ACC_SYNTHETIC) != 0; @@ -304,9 +327,13 @@ class ClassFileVisitor extends Tester.Visitor { } } else if (index == 0) { if (isAnon) { + expect = "this\\$[0-9]+"; allowMandated = true; - expect = "this\\$[0-n]*"; + if (isFinal) { + expect = "final this\\$[0-9]+"; + } } else if (isInner && !isStatic) { + expect = "this\\$[0-9]+"; allowMandated = true; if (!isPublic) { // some but not all non-public inner classes @@ -314,7 +341,9 @@ class ClassFileVisitor extends Tester.Visitor { // the test a bit of slack and allow either. allowSynthetic = true; } - expect = "this\\$[0-n]*"; + if (isFinal) { + expect = "final this\\$[0-9]+"; + } } } } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) { @@ -327,8 +356,8 @@ class ClassFileVisitor extends Tester.Visitor { */ expect = null; } - if (mandated) sb.append("!"); - if (synthetic) sb.append("!!"); + if (mandated) sb.append("/*implicit*/"); + if (synthetic) sb.append("/*synthetic*/"); // IMPL: our rules a somewhat fuzzy, sometimes allowing both mandated // and synthetic. However, a parameters cannot be both. diff --git a/langtools/test/tools/javac/MethodParameters/Constructors.java b/langtools/test/tools/javac/MethodParameters/Constructors.java index a4428d4126e..5fc71ee81b7 100644 --- a/langtools/test/tools/javac/MethodParameters/Constructors.java +++ b/langtools/test/tools/javac/MethodParameters/Constructors.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters Constructors.java - * @run main Tester Constructors + * @run main Tester Constructors Constructors.out */ public class Constructors { diff --git a/langtools/test/tools/javac/MethodParameters/Constructors.out b/langtools/test/tools/javac/MethodParameters/Constructors.out new file mode 100644 index 00000000000..7f781c30c5e --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/Constructors.out @@ -0,0 +1,5 @@ +public class Constructors -- +Constructors.() +Constructors.(final a, final ba) +Constructors.(a, final ba, final cba) +Constructors.(a, ba, final cba, final dcba) \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/EnumTest.java b/langtools/test/tools/javac/MethodParameters/EnumTest.java index 2f6cde31713..f4aa5f41010 100644 --- a/langtools/test/tools/javac/MethodParameters/EnumTest.java +++ b/langtools/test/tools/javac/MethodParameters/EnumTest.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters EnumTest.java - * @run main Tester EnumTest + * @run main Tester EnumTest EnumTest.out */ /** Test that parameter names are recorded for enum methods */ diff --git a/langtools/test/tools/javac/MethodParameters/EnumTest.out b/langtools/test/tools/javac/MethodParameters/EnumTest.out new file mode 100644 index 00000000000..f3e4d04d07b --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/EnumTest.out @@ -0,0 +1,7 @@ +enum EnumTest -- +EnumTest.($enum$name/*synthetic*/, $enum$ordinal/*synthetic*/) +EnumTest.($enum$name/*synthetic*/, $enum$ordinal/*synthetic*/, a, ba) +EnumTest.ok(c, dc) +EnumTest.values() +EnumTest.valueOf(A, BA) +EnumTest.valueOf(name/*implicit*/) \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/InstanceMethods.java b/langtools/test/tools/javac/MethodParameters/InstanceMethods.java index d3c87b556dc..373b59ef0b5 100644 --- a/langtools/test/tools/javac/MethodParameters/InstanceMethods.java +++ b/langtools/test/tools/javac/MethodParameters/InstanceMethods.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters InstanceMethods.java - * @run main Tester InstanceMethods + * @run main Tester InstanceMethods InstanceMethods.out */ public class InstanceMethods { diff --git a/langtools/test/tools/javac/MethodParameters/InstanceMethods.out b/langtools/test/tools/javac/MethodParameters/InstanceMethods.out new file mode 100644 index 00000000000..3a7c3ee1a2f --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/InstanceMethods.out @@ -0,0 +1,11 @@ +public class InstanceMethods -- +InstanceMethods.() +InstanceMethods.empty() +InstanceMethods.def(a, final ba, final cba) +InstanceMethods.pub(d, final ed, final fed) +InstanceMethods.prot(g, final hg, final ihg) +InstanceMethods.priv(j, final kj, final lkj) +InstanceMethods.def(A, BA, final CBA, final DCBA) +InstanceMethods.pub(B, CB, final DCB, final EDCB) +InstanceMethods.prot(C, DC, final EDC, final FEDC) +InstanceMethods.priv(D, ED, final FED, final GFED) \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/LambdaTest.java b/langtools/test/tools/javac/MethodParameters/LambdaTest.java index 931b1510b50..d71568249fd 100644 --- a/langtools/test/tools/javac/MethodParameters/LambdaTest.java +++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters LambdaTest.java - * @run main Tester LambdaTest + * @run main Tester LambdaTest LambdaTest.out */ /** diff --git a/langtools/test/tools/javac/MethodParameters/LambdaTest.out b/langtools/test/tools/javac/MethodParameters/LambdaTest.out new file mode 100644 index 00000000000..7cfdfe9058a --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.out @@ -0,0 +1,7 @@ +class LambdaTest -- +LambdaTest.() +LambdaTest.foo(i) +LambdaTest.lambda$1(arg0, arg1)/*synthetic*/ +LambdaTest.lambda$0(arg0)/*synthetic*/ +static interface LambdaTest$I -- inner +LambdaTest$I.m(x) \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/LocalClassTest.java b/langtools/test/tools/javac/MethodParameters/LocalClassTest.java index 101b27645db..250d4212fdc 100644 --- a/langtools/test/tools/javac/MethodParameters/LocalClassTest.java +++ b/langtools/test/tools/javac/MethodParameters/LocalClassTest.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters LocalClassTest.java - * @run main Tester LocalClassTest + * @run main Tester LocalClassTest LocalClassTest.out */ class LocalClassTest { diff --git a/langtools/test/tools/javac/MethodParameters/LocalClassTest.out b/langtools/test/tools/javac/MethodParameters/LocalClassTest.out new file mode 100644 index 00000000000..24eda916fb1 --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/LocalClassTest.out @@ -0,0 +1,12 @@ +class LocalClassTest$1Local_has_constructor -- inner +LocalClassTest$1Local_has_constructor.(final this$0/*implicit*/, a, ba) +LocalClassTest$1Local_has_constructor.(final this$0/*implicit*/) +LocalClassTest$1Local_has_constructor.foo(m, nm) +LocalClassTest$1Local_has_constructor.foo() +class LocalClassTest$1Local_default_constructor -- inner +LocalClassTest$1Local_default_constructor.(final this$0/*implicit*/) +LocalClassTest$1Local_default_constructor.foo() +LocalClassTest$1Local_default_constructor.foo(m, nm) +class LocalClassTest -- +LocalClassTest.() +LocalClassTest.foo() \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/MemberClassTest.java b/langtools/test/tools/javac/MethodParameters/MemberClassTest.java index 69482d724b7..83cd883c14b 100644 --- a/langtools/test/tools/javac/MethodParameters/MemberClassTest.java +++ b/langtools/test/tools/javac/MethodParameters/MemberClassTest.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters MemberClassTest.java - * @run main Tester MemberClassTest + * @run main Tester MemberClassTest MemberClassTest.out */ class MemberClassTest { diff --git a/langtools/test/tools/javac/MethodParameters/MemberClassTest.out b/langtools/test/tools/javac/MethodParameters/MemberClassTest.out new file mode 100644 index 00000000000..a5b368fc18a --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/MemberClassTest.out @@ -0,0 +1,33 @@ +static class MemberClassTest$Static_Member -- inner +MemberClassTest$Static_Member.() +MemberClassTest$Static_Member.(arg, barg) +MemberClassTest$Static_Member.m(s, ts) +MemberClassTest$Static_Member.m() +public class MemberClassTest$Member -- inner +MemberClassTest$Member.(final this$0/*implicit*/) +MemberClassTest$Member.(final this$0/*implicit*/, a, ba) +MemberClassTest$Member.m(s, ts) +MemberClassTest$Member.m() +public class MemberClassTest$Member$Member_Member -- inner +MemberClassTest$Member$Member_Member.(final this$1/*implicit*/) +MemberClassTest$Member$Member_Member.(final this$1/*implicit*/, x, yx) +class MemberClassTest$1 -- anon +MemberClassTest$1.(final this$0/*implicit*/) +MemberClassTest$1.m() +MemberClassTest$1.m(s, ts) +static public class MemberClassTest$Static_Member$Static_Member_Static_Member -- inner +MemberClassTest$Static_Member$Static_Member_Static_Member.() +MemberClassTest$Static_Member$Static_Member_Static_Member.(x, yx) +public class MemberClassTest$Static_Member$Static_Member_Member -- inner +MemberClassTest$Static_Member$Static_Member_Member.(final this$0/*implicit*/) +MemberClassTest$Static_Member$Static_Member_Member.(final this$0/*implicit*/, x, yx) +class MemberClassTest -- +MemberClassTest.(final a, ba) +MemberClassTest.() +MemberClassTest.foo() +static interface MemberClassTest$I -- inner +MemberClassTest$I.m() +MemberClassTest$I.m(x, yx) +class MemberClassTest$1$Anonymous_Member -- inner +MemberClassTest$1$Anonymous_Member.(final this$1/*implicit*/) +MemberClassTest$1$Anonymous_Member.(final this$1/*implicit*/, x, yx) \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java index 841e70cbea2..8102854d511 100644 --- a/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java +++ b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java @@ -48,6 +48,7 @@ public class ReflectionVisitor extends Tester.Visitor { boolean isMember; boolean isStatic; boolean isPublic; + boolean isFinal; Class clazz; StringBuilder sb; @@ -72,8 +73,8 @@ public class ReflectionVisitor extends Tester.Visitor { .append(isPublic ? "public " : "") .append(isEnum ? "enum " : isInterface ? "interface " : "class ") .append(cl).append(" -- ") - .append(isMember? "member " : "" ) - .append(isLocal? "local " : "" ) + .append(isMember? "inner" : "" ) + .append(isLocal? "inner" : "" ) .append(isAnon ? "anon" : "") .append("\n"); @@ -82,7 +83,6 @@ public class ReflectionVisitor extends Tester.Visitor { } for (Method m :clazz.getDeclaredMethods()) { - testMethod(m); } } @@ -116,9 +116,15 @@ public class ReflectionVisitor extends Tester.Visitor { for (Parameter p : c.getParameters()) { i++; String pname = p.getName(); + int pmodifier = p.getModifiers(); + isFinal = false; + if (Modifier.isFinal(pmodifier)) { + isFinal = true; + pname = "final " + pname; + } sb.append(sep).append(pname); - if (p.isImplicit()) sb.append("!"); - if (p.isSynthetic()) sb.append("!!"); + if (p.isImplicit()) sb.append("/*implicit*/"); + if (p.isSynthetic()) sb.append("/*synthetic*/"); sep = ", "; // Set expectations @@ -135,11 +141,17 @@ public class ReflectionVisitor extends Tester.Visitor { } } else if (i == 0) { if (isAnon) { + expect = "this\\$[0-9]+"; allowImplicit = true; + if (isFinal) + expect = "final this\\$[0-9]+"; } else if (isLocal) { + expect = "this\\$[0-9]+"; allowImplicit = true; - expect = "this\\$[0-n]*"; + if (isFinal) + expect = "final this\\$[0-9]+"; } else if ((isMember && !isStatic)) { + expect = "this\\$[0-9]+"; allowImplicit = true; if (!isPublic) { // some but not all non-public inner classes @@ -147,7 +159,8 @@ public class ReflectionVisitor extends Tester.Visitor { // the test a bit of slack and allow either. allowSynthetic = true; } - expect = "this\\$[0-n]*"; + if (isFinal) + expect = "final this\\$[0-9]+"; } } @@ -201,11 +214,16 @@ public class ReflectionVisitor extends Tester.Visitor { char ch = param.charAt(0); expect = (++ch) + param; } - + if (isFinal && expect != null) { + expect = "final " + expect; + } if (pname != null && fidelity) { + if (isFinal) { + param = pname.substring(6); + } else { param = pname; } - + } if (expect != null && !expect.equals(pname)) { error(prefix + "param[" + i + "]='" + pname + "' expected '" + expect + "'"); @@ -213,7 +231,7 @@ public class ReflectionVisitor extends Tester.Visitor { } } if (c.isSynthetic()) { - sb.append(")!!\n"); + sb.append(")/*synthetic*/\n"); } else { sb.append(")\n"); } @@ -240,13 +258,24 @@ public class ReflectionVisitor extends Tester.Visitor { // the test-case design pattern, except synthetic methods. for (Parameter p : m.getParameters()) { i++; + isFinal = false; + int pmodifier = p.getModifiers(); if (param == null) { param = p.getName(); + if (Modifier.isFinal(pmodifier)) { + isFinal = true; + param = "final " + param; + } sb.append(sep).append(param); } else { char c = param.charAt(0); String expect = m.isSynthetic() ? ("arg" + i) : ((++c) + param); param = p.getName(); + if (Modifier.isFinal(pmodifier)) { + isFinal = true; + expect = "final " + expect; + param = "final " + param; + } sb.append(sep).append(param); if (!m.isBridge() && !expect.equals(param)) { error(prefix + "param[" + i + "]='" @@ -254,10 +283,18 @@ public class ReflectionVisitor extends Tester.Visitor { break; } } + if(isFinal) + param = param.substring(6); + if (p.isImplicit()) { + sb.append("/*implicit*/"); + } + if (p.isSynthetic()) { + sb.append("/*synthetic*/"); + } sep = ", "; } if (m.isSynthetic()) { - sb.append(")!!\n"); + sb.append(")/*synthetic*/\n"); } else { sb.append(")\n"); } diff --git a/langtools/test/tools/javac/MethodParameters/StaticMethods.java b/langtools/test/tools/javac/MethodParameters/StaticMethods.java index 5e1ade474cd..12e4225815d 100644 --- a/langtools/test/tools/javac/MethodParameters/StaticMethods.java +++ b/langtools/test/tools/javac/MethodParameters/StaticMethods.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters StaticMethods.java - * @run main Tester StaticMethods + * @run main Tester StaticMethods StaticMethods.out */ public class StaticMethods { diff --git a/langtools/test/tools/javac/MethodParameters/StaticMethods.out b/langtools/test/tools/javac/MethodParameters/StaticMethods.out new file mode 100644 index 00000000000..9ff4b0077b2 --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/StaticMethods.out @@ -0,0 +1,11 @@ +public class StaticMethods -- +StaticMethods.() +StaticMethods.def(a, ba, final cba, final dcba) +StaticMethods.def(a, final ba, final cba) +StaticMethods.pub(d, final ed, final fed) +StaticMethods.pub(a, ba, final cba, final dcba) +StaticMethods.prot(g, final hg, final ihg) +StaticMethods.prot(aa, baa, final cbaa, final dcbaa) +StaticMethods.priv(j, final kj, final lkj) +StaticMethods.priv(abc, babc, final cbabc, final dcbabc) +StaticMethods.empty() \ No newline at end of file diff --git a/langtools/test/tools/javac/MethodParameters/Tester.java b/langtools/test/tools/javac/MethodParameters/Tester.java index 84b2dddb5e4..4b3bb04580f 100644 --- a/langtools/test/tools/javac/MethodParameters/Tester.java +++ b/langtools/test/tools/javac/MethodParameters/Tester.java @@ -23,6 +23,12 @@ import java.io.*; import java.lang.reflect.Constructor; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Test driver for MethodParameters testing. @@ -44,6 +50,13 @@ public class Tester { final static File classesdir = new File(System.getProperty("test.classes", ".")); + private String classname; + private File[] files; + private File refFile; + private int errors; + private int warnings; + private int diffGolden; + /** * The visitor classes that does the actual checking are referenced * statically, to force compilations, without having to reference @@ -62,32 +75,38 @@ public class Tester { * Test-driver expect a single classname as argument. */ public static void main(String... args) throws Exception { - if (args.length != 1) { - throw new Error("A single class name is expected as argument"); + if (args.length != 2) { + throw new Error("A single class name and a golden file are expected as argument"); } - final String pattern = args[0] + ".*\\.class"; - File files[] = classesdir.listFiles(new FileFilter() { + String testSrc = System.getProperty("test.src"); + String testName = args[0]; + String testGoldenFile = args[1]; + final String pattern = testName + ".*\\.class"; + File refFile = new File(testSrc, testGoldenFile); + File[] files = classesdir.listFiles(new FileFilter() { public boolean accept(File f) { return f.getName().matches(pattern); } }); if (files.length == 0) { - File file = new File(classesdir, args[0] + ".class"); + File file = new File(classesdir, testName + ".class"); throw new Error(file.getPath() + " not found"); } - new Tester(args[0], files).run(); + new Tester(testName, files, refFile).run(); } - public Tester(String name, File files[]) { + public Tester(String name, File[] files, File refFile) { this.classname = name; this.files = files; + this.refFile = refFile; } void run() throws Exception { // Test with each visitor for (Class vclass : visitors) { + boolean compResult = false; try { String vname = vclass.getName(); Constructor c = vclass.getConstructor(Tester.class); @@ -105,12 +124,21 @@ public class Tester { e.printStackTrace(); } } - info(sb.toString()); + String output = sb.toString(); + info(output); + compResult = compareOutput(refFile, output); } catch(ReflectiveOperationException e) { warn("Class " + vclass.getName() + " ignored, not a Visitor"); continue; } + if (!compResult) { + diffGolden++; + error("The output from " + vclass.getName() + " did not match golden file."); } + } + + if (0 != diffGolden) + throw new Exception("Test output is not equal with golden file."); if(0 != warnings) System.err.println("Test generated " + warnings + " warnings"); @@ -119,6 +147,25 @@ public class Tester { throw new Exception("Tester test failed with " + errors + " errors"); } + // Check if test output matches the golden file. + boolean compareOutput(File refFile, String sb) + throws FileNotFoundException, IOException { + + List refFileList = Files.readAllLines(refFile.toPath(), StandardCharsets.UTF_8); + List sbList = Arrays.asList(sb.split(System.getProperty("line.separator"))); + // Check if test output contains unexpected lines or is missing expected lines. + List sbOnly = new ArrayList(sbList); + sbOnly.removeAll(refFileList); + for (String line: sbOnly) + error("unexpected line found: " + line); + + List refOnly = new ArrayList(refFileList); + refOnly.removeAll(sbList); + for (String line: refOnly) + error("expected line not found: " + line); + + return sbOnly.isEmpty() && refOnly.isEmpty(); + } abstract static class Visitor { Tester tester; @@ -153,9 +200,4 @@ public class Tester { void info(String msg) { System.out.println(msg); } - - int errors; - int warnings; - String classname; - File files[]; } diff --git a/langtools/test/tools/javac/MethodParameters/UncommonParamNames.java b/langtools/test/tools/javac/MethodParameters/UncommonParamNames.java index 62534d61542..5915600115d 100644 --- a/langtools/test/tools/javac/MethodParameters/UncommonParamNames.java +++ b/langtools/test/tools/javac/MethodParameters/UncommonParamNames.java @@ -27,7 +27,7 @@ * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters UncommonParamNames.java - * @run main Tester UncommonParamNames + * @run main Tester UncommonParamNames UncommonParamNames.out */ /** Test uncommon parameter names */ diff --git a/langtools/test/tools/javac/MethodParameters/UncommonParamNames.out b/langtools/test/tools/javac/MethodParameters/UncommonParamNames.out new file mode 100644 index 00000000000..e1eff4446bc --- /dev/null +++ b/langtools/test/tools/javac/MethodParameters/UncommonParamNames.out @@ -0,0 +1,17 @@ +class UncommonParamNames -- +UncommonParamNames.(zerozero) +UncommonParamNames.(a) +UncommonParamNames.($1) +UncommonParamNames.(_x) +UncommonParamNames.(a, ba, cba, dcba, edcba, fedcba, gfedcba, hgfedcba, ihgfedcba, jihgfedcba, kjihgfedcba, lkjihgfedcba, mlkjihgfedcba, nmlkjihgfedcba, onmlkjihgfedcba, ponmlkjihgfedcba, qponmlkjihgfedcba, rqponmlkjihgfedcba, srqponmlkjihgfedcba, tsrqponmlkjihgfedcba, utsrqponmlkjihgfedcba, vutsrqponmlkjihgfedcba, wvutsrqponmlkjihgfedcba, xwvutsrqponmlkjihgfedcba, yxwvutsrqponmlkjihgfedcba, zyxwvutsrqponmlkjihgfedcba) +UncommonParamNames.(aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName) +UncommonParamNames.(zerozeroeight) +UncommonParamNames.(zerozeroseven) +UncommonParamNames.foo(zerozero) +UncommonParamNames.foo(a) +UncommonParamNames.foo($1) +UncommonParamNames.foo(a, ba, cba, dcba, edcba, fedcba, gfedcba, hgfedcba, ihgfedcba, jihgfedcba, kjihgfedcba, lkjihgfedcba, mlkjihgfedcba, nmlkjihgfedcba, onmlkjihgfedcba, ponmlkjihgfedcba, qponmlkjihgfedcba, rqponmlkjihgfedcba, srqponmlkjihgfedcba, tsrqponmlkjihgfedcba, utsrqponmlkjihgfedcba, vutsrqponmlkjihgfedcba, wvutsrqponmlkjihgfedcba, xwvutsrqponmlkjihgfedcba, yxwvutsrqponmlkjihgfedcba, zyxwvutsrqponmlkjihgfedcba) +UncommonParamNames.foo(zerozeroseven) +UncommonParamNames.foo(zerozeroeight) +UncommonParamNames.foo(aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName) +UncommonParamNames.foo(_x) \ No newline at end of file From c57660ca19490202ab5af94b75438daa1367696c Mon Sep 17 00:00:00 2001 From: Matherey Nunez Date: Thu, 17 Oct 2013 13:50:00 +0200 Subject: [PATCH 115/152] 8008192: Better ordering checks needed in repeatingAnnotations/combo/ReflectionTest Reviewed-by: jjg, jfranck --- .../repeatingAnnotations/combo/Helper.java | 8 +- .../combo/ReflectionTest.java | 536 ++++++++++-------- 2 files changed, 317 insertions(+), 227 deletions(-) diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java index 0aee99c4010..97bfdb355e9 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java @@ -54,10 +54,10 @@ public class Helper { IMPORTEXPECTED("import expectedFiles.*;\n"), REPEATABLE("\n@Repeatable(FooContainer.class)\n"), CONTAINER("@interface FooContainer {\n" + " Foo[] value();\n}\n"), - BASE("@interface Foo {}\n"), - BASEANNO("@Foo"), - LEGACYCONTAINER("@FooContainer(value = {@Foo, @Foo})\n"), - REPEATABLEANNO("\n@Foo() @Foo()"), + BASE("@interface Foo {int value() default Integer.MAX_VALUE;}\n"), + BASEANNO("@Foo(0)"), + LEGACYCONTAINER("@FooContainer(value = {@Foo(1), @Foo(2)})\n"), + REPEATABLEANNO("\n@Foo(1) @Foo(2)"), DEPRECATED("\n@Deprecated"), DOCUMENTED("\n@Documented"), INHERITED("\n@Inherited"), diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/ReflectionTest.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/ReflectionTest.java index 419af33264a..f0dbe37f49f 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/ReflectionTest.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/ReflectionTest.java @@ -45,6 +45,8 @@ import javax.tools.JavaFileObject; import expectedFiles.ExpectedBase; import expectedFiles.ExpectedContainer; +import java.util.Iterator; +import java.util.regex.Pattern; /* * Objective: @@ -99,6 +101,7 @@ public class ReflectionTest { * Set it to true to get more debug information */ static final boolean DEBUG = false; + static boolean CHECKORDERING; public static void main(String args[]) throws Exception { ReflectionTest test = new ReflectionTest(); @@ -145,6 +148,23 @@ public class ReflectionTest { if (c != null) { // For the loaded class object, compare expected and actual annotation values // for each of the methods under test from java.lang.reflect.AnnotatedElement + + + // Ignoring following test cases since for now they are + // failing with ordering issues. + // @ignore 8025924: Several test cases in repeatingAnnotations/combo/ReflectionTest + // fail with ordering issues + List orderingTestFailures = Arrays.asList( + "SingleOnSuperContainerOnSub_Inherited_Legacy", + "SingleOnSuperContainerAndSingleOnSub_Inherited_Legacy", + "ContainerAndSingleOnSuperSingleOnSub_Inherited_Legacy", + "SingleAnnoWithContainer", + "SingleOnSuperContainerAndSingleOnSub_Inherited"); + if (orderingTestFailures.contains(testCase.toString())) { + CHECKORDERING = false; + } else + CHECKORDERING = true; + checkAnnoValues(srcType, c); } else { error("Could not load className = " + c); @@ -167,12 +187,12 @@ public class ReflectionTest { enum TestCase { BasicNonRepeatable_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " - + "getDeclAnnoVal = \"Foo\", " - + "getAnnosArgs = {\"Foo\"}, " - + "getDeclAnnosArgs = {\"Foo\"}) ", + + "getAnnotationVal = \"@Foo(value=0)\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\"}, " + + "getDeclAnnoVal = \"@Foo(value=0)\", " + + "getAnnosArgs = {\"@Foo(value=0)\"}, " + + "getDeclAnnosArgs = {\"@Foo(value=0)\"}) ", "@ExpectedContainer") { @Override @@ -202,11 +222,11 @@ public class ReflectionTest { Sample package-info.java @ExpectedBase @ExpectedContainer - @Foo + @Foo(0) package testpkg; @Retention(RetentionPolicy.RUNTIME) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} Sample testSrc: package testpkg; @@ -229,11 +249,11 @@ public class ReflectionTest { /* Sample testSrc for class @Retention(RetentionPolicy.RUNTIME) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @ExpectedBase @ExpectedContainer - @Foo + @Foo(0) class A {} */ replaceVal = expectedVals + anno; @@ -248,11 +268,11 @@ public class ReflectionTest { }, SingleAnnoInherited_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " - + "getAnnotationsVals = {\"Foo\", \"ExpectedBase\", \"ExpectedContainer\"}, " + + "getAnnotationVal = \"@Foo(value=0)\", " + + "getAnnotationsVals = {\"@Foo(value=0)\", \"ExpectedBase\", \"ExpectedContainer\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\"}, " + "getDeclAnnoVal = \"NULL\", " - + "getAnnosArgs = {\"Foo\"}, " + + "getAnnosArgs = {\"@Foo(value=0)\"}, " + "getDeclAnnosArgs = {})", "@ExpectedContainer") { @@ -273,9 +293,9 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} - @Foo + @Foo(0) class SuperClass { } @ExpectedBase @@ -337,9 +357,9 @@ public class ReflectionTest { Sample test src: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} - @Foo + @Foo(0) interface TestInterface { } @ExpectedBase @@ -375,18 +395,18 @@ public class ReflectionTest { }, AnnoOnSuperAndSubClass_Inherited_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " + + "getAnnotationVal = \"@Foo(value=2)\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=2)\"}, " + // override every annotation on superClass - "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=2)\"}, " + // ignores inherited annotations - "getDeclAnnoVal = \"Foo\", " // ignores inherited - + "getAnnosArgs = {\"Foo\"}, " - + "getDeclAnnosArgs = { \"Foo\" })", // ignores inherited + "getDeclAnnoVal = \"@Foo(value=2)\", " // ignores inherited + + "getAnnosArgs = {\"@Foo(value=2)\"}, " + + "getDeclAnnosArgs = { \"@Foo(value=2)\" })", // ignores inherited "@ExpectedContainer(value=FooContainer.class, " + "getAnnotationVal = \"NULL\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=2)\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=2)\"}, " + // ignores inherited annotations "getDeclAnnoVal = \"NULL\", " + // ignores inherited "getAnnosArgs = {}, " + "getDeclAnnosArgs = {})") { // ignores inherited @@ -408,19 +428,19 @@ public class ReflectionTest { Sample test src @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Inherited @interface FooContainer { Foo[] value(); } - @Foo + @Foo(1) class SuperClass { } @ExpectedBase @ExpectedContainer - @Foo + @Foo(2) class SubClass extends SuperClass {} */ // @Inherited only works for classes, no switch cases for @@ -435,12 +455,13 @@ public class ReflectionTest { if (srcType == SrcType.CLASS) { // Contents for SuperClass - anno = Helper.ContentVars.BASEANNO.getVal(); + anno = "@Foo(1)"; replaceVal = commonStmts + "\n" + anno; String superClassContents = srcType.getTemplate() .replace("#CN", SUPERCLASS).replace("#REPLACE", replaceVal); // Contents for SubClass that extends SuperClass + anno = "@Foo(2)"; replaceVal = expectedVals + "\n" + anno; String subClassContents = SrcType.CLASSEXTENDS.getTemplate() .replace("#CN", className).replace("#SN", SUPERCLASS) @@ -456,17 +477,17 @@ public class ReflectionTest { BasicContainer_Legacy( "@ExpectedBase(value = Foo.class, " + "getAnnotationVal = \"NULL\"," - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnoVal = \"NULL\", " + "getAnnosArgs = {}, " + "getDeclAnnosArgs = {} )", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " - + "getDeclAnnoVal = \"FooContainer\", " - + "getAnnosArgs = {\"FooContainer\"}, " - + "getDeclAnnosArgs = {\"FooContainer\"} )") { + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"} )") { @Override public Iterable getTestFiles(SrcType srcType, @@ -498,11 +519,11 @@ public class ReflectionTest { Sample package-info.java @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) package testpkg; @Retention(RetentionPolicy.RUNTIME) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -529,7 +550,7 @@ public class ReflectionTest { Sample testSrc for class: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -539,7 +560,7 @@ public class ReflectionTest { @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) class A {} */ replaceVal = expectedVals + anno; @@ -554,23 +575,23 @@ public class ReflectionTest { }, SingleAndContainerOnSuper_Legacy( "@ExpectedBase(value = Foo.class, " - + "getAnnotationVal = \"Foo\"," + + "getAnnotationVal = \"@Foo(value=0)\"," + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnoVal = \"Foo\", " - + "getAnnosArgs = {\"Foo\"}, " - + "getDeclAnnosArgs = {\"Foo\"} )", + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnoVal = \"@Foo(value=0)\", " + + "getAnnosArgs = {\"@Foo(value=0)\"}, " + + "getDeclAnnosArgs = {\"@Foo(value=0)\"} )", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnoVal = \"FooContainer\", " - + "getAnnosArgs = {\"FooContainer\"}, " - + "getDeclAnnosArgs = {\"FooContainer\"} )") { + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"} )") { @Override public Iterable getTestFiles(SrcType srcType, @@ -589,8 +610,8 @@ public class ReflectionTest { + getExpectedContainer() + "\n"; StringBuilder commonStmts = new StringBuilder(); - anno = Helper.ContentVars.LEGACYCONTAINER.getVal() - + Helper.ContentVars.BASEANNO.getVal(); + anno = Helper.ContentVars.BASEANNO.getVal() + + Helper.ContentVars.LEGACYCONTAINER.getVal(); commonStmts.append(Helper.ContentVars.IMPORTEXPECTED.getVal()) .append(Helper.ContentVars.IMPORTSTMTS.getVal()) .append(Helper.ContentVars.RETENTIONRUNTIME.getVal()) @@ -603,12 +624,12 @@ public class ReflectionTest { Sample package-info.java @ExpectedBase @ExpectedContainer - @Foo - @FooContainer(value = {@Foo, @Foo}) + @Foo(0) + @FooContainer(value = {@Foo(1), @Foo(2)}) package testpkg; @Retention(RetentionPolicy.RUNTIME) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -636,7 +657,7 @@ public class ReflectionTest { Sample testSrc for class: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -646,8 +667,8 @@ public class ReflectionTest { @ExpectedBase @ExpectedContainer - @Foo - @FooContainer(value = {@Foo, @Foo}) + @Foo(0) + @FooContainer(value = {@Foo(1), @Foo(2)}) class A {} */ replaceVal = expectedVals + anno; @@ -664,17 +685,17 @@ public class ReflectionTest { BasicContainer_Inherited_Legacy( "@ExpectedBase(value = Foo.class, " + "getAnnotationVal = \"NULL\"," - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\"}, " + "getDeclAnnoVal = \"NULL\", " + "getAnnosArgs = {}, " + "getDeclAnnosArgs = {} )", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\"}, " + "getDeclAnnoVal = \"NULL\", " - + "getAnnosArgs = {\"FooContainer\"}, " + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosArgs = {} )") { @Override @@ -694,7 +715,7 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -702,7 +723,7 @@ public class ReflectionTest { Foo[] value(); } - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) class SuperClass { } @ExpectedBase @@ -736,20 +757,20 @@ public class ReflectionTest { }, ContainerOnSuperSingleOnSub_Inherited_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " + + "getAnnotationVal = \"@Foo(value=0)\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}," - + "getDeclAnnoVal = \"Foo\"," - + "getAnnosArgs = {\"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\"})", + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=0)\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\"}," + + "getDeclAnnoVal = \"@Foo(value=0)\"," + + "getAnnosArgs = {\"@Foo(value=0)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=0)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=0)\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\"}," + "getDeclAnnoVal = \"NULL\"," - + "getAnnosArgs = {\"FooContainer\"}," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnosArgs = {})") { @Override @@ -769,7 +790,7 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -777,12 +798,12 @@ public class ReflectionTest { Foo[] value(); } - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) class SuperClass { } @ExpectedBase @ExpectedContainer - @Foo + @Foo(0) class SubClass extends SuperClass {} */ // @Inherited only works for classes, no switch cases for @@ -811,22 +832,24 @@ public class ReflectionTest { return files; } }, + // @ignore 8025924: Several test cases in repeatingAnnotations/combo/ReflectionTest + // fail with ordering issues ContainerAndSingleOnSuperSingleOnSub_Inherited_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " + + "getAnnotationVal = \"@Foo(value=0)\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}," - + "getDeclAnnoVal = \"Foo\"," - + "getAnnosArgs = {\"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\"})", + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=0)\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\"}," + + "getDeclAnnoVal = \"@Foo(value=0)\"," + + "getAnnosArgs = {\"@Foo(value=0)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=0)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=0)\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\"}," + "getDeclAnnoVal = \"NULL\"," - + "getAnnosArgs = {\"FooContainer\"}," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnosArgs = {})") { @Override @@ -846,7 +869,7 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -854,12 +877,12 @@ public class ReflectionTest { Foo[] value(); } - @FooContainer(value = {@Foo, @Foo}) @Foo + @FooContainer(value = {@Foo(1), @Foo(2)}) @Foo(3) class SuperClass { } @ExpectedBase @ExpectedContainer - @Foo + @Foo(0) class SubClass extends SuperClass {} */ // @Inherited only works for classes, no switch cases for @@ -868,7 +891,7 @@ public class ReflectionTest { if (srcType == SrcType.CLASS) { // Contents for SuperClass anno = Helper.ContentVars.LEGACYCONTAINER.getVal() - + Helper.ContentVars.BASEANNO.getVal(); + + "@Foo(3)"; replaceVal = commonStmts + "\n" + anno; String superClassContents = srcType.getTemplate() .replace("#CN", SUPERCLASS) @@ -888,23 +911,25 @@ public class ReflectionTest { return files; } }, + // @ignore 8025924: Several test cases in repeatingAnnotations/combo/ReflectionTest + // fail with ordering issues SingleOnSuperContainerOnSub_Inherited_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " + + "getAnnotationVal = \"@Foo(value=0)\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnoVal = \"NULL\"," - + "getAnnosArgs = {\"Foo\"}," + + "getAnnosArgs = {\"@Foo(value=0)\"}," + "getDeclAnnosArgs = {})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}," - + "getDeclAnnoVal = \"FooContainer\"," - + "getAnnosArgs = {\"FooContainer\"}," - + "getDeclAnnosArgs = {\"FooContainer\"})") { + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"})") { @Override public Iterable getTestFiles(SrcType srcType, @@ -924,7 +949,7 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -932,12 +957,12 @@ public class ReflectionTest { Foo[] value(); } - @Foo + @Foo(0) class SuperClass { } @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) class SubClass extends SuperClass {} */ @@ -963,25 +988,27 @@ public class ReflectionTest { return files; } }, + // @ignore 8025924: Several test cases in repeatingAnnotations/combo/ReflectionTest + // fail with ordering issues SingleOnSuperContainerAndSingleOnSub_Inherited_Legacy( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " + + "getAnnotationVal = \"@Foo(value=3)\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," - + "getDeclAnnoVal = \"Foo\"," - + "getAnnosArgs = {\"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\"})", + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}," + + "getDeclAnnoVal = \"@Foo(value=3)\"," + + "getAnnosArgs = {\"@Foo(value=3)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=3)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," - + "getDeclAnnoVal = \"FooContainer\"," - + "getAnnosArgs = {\"FooContainer\"}," - + "getDeclAnnosArgs = {\"FooContainer\"})") { + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}," + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"})") { @Override public Iterable getTestFiles(SrcType srcType, @@ -1001,7 +1028,7 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -1009,12 +1036,12 @@ public class ReflectionTest { Foo[] value(); } - @Foo + @Foo(0) class SuperClass { } @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) @Foo + @FooContainer(value = {@Foo(1), @Foo(2)}) @Foo(3) class SubClass extends SuperClass {} */ @@ -1028,7 +1055,7 @@ public class ReflectionTest { //Contents for SubClass that extends SuperClass anno = Helper.ContentVars.LEGACYCONTAINER.getVal() - + Helper.ContentVars.BASEANNO.getVal(); + + "@Foo(3)"; replaceVal = expectedVals + "\n" + anno; String subClassContents = SrcType.CLASSEXTENDS.getTemplate() .replace("#CN", className).replace("#SN", SUPERCLASS) @@ -1044,18 +1071,18 @@ public class ReflectionTest { BasicRepeatable( "@ExpectedBase(value=Foo.class, " + "getAnnotationVal = \"NULL\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\" }, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}," + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\" }, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnoVal = \"NULL\"," - + "getAnnosArgs = {\"Foo\", \"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\", \"Foo\"})", + + "getAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\"," - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}," - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " - + "getDeclAnnoVal = \"FooContainer\"," - + "getAnnosArgs = {\"FooContainer\"}," - + "getDeclAnnosArgs = {\"FooContainer\"} )") { + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"} )") { @Override public Iterable getTestFiles(SrcType srcType, @@ -1088,12 +1115,12 @@ public class ReflectionTest { Sample package-info.java @ExpectedBase @ExpectedContainer - @Foo() @Foo() + @Foo(1) @Foo(2) package testpkg; @Retention(RetentionPolicy.RUNTIME) @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -1120,7 +1147,7 @@ public class ReflectionTest { Sample testSrc for class: @Retention(RetentionPolicy.RUNTIME) @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -1129,7 +1156,7 @@ public class ReflectionTest { @ExpectedBase @ExpectedContainer - @Foo @Foo + @Foo(1) @Foo(2) class A { } */ replaceVal = expectedVals + anno; @@ -1146,21 +1173,21 @@ public class ReflectionTest { "@ExpectedBase(value=Foo.class, " + "getAnnotationVal = \"NULL\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnoVal = \"NULL\"," - + "getAnnosArgs = {\"Foo\", \"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\", \"Foo\"})", + + "getAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\"," + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " - + "getDeclAnnoVal = \"FooContainer\"," - + "getAnnosArgs = {\"FooContainer\"}," - + "getDeclAnnosArgs = {\"FooContainer\"} )") { + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"} )") { @Override public Iterable getTestFiles(SrcType srcType, @@ -1193,12 +1220,12 @@ public class ReflectionTest { Sample package-info.java @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) package testpkg; @Retention(RetentionPolicy.RUNTIME) @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -1225,7 +1252,7 @@ public class ReflectionTest { Sample testSrc for class: @Retention(RetentionPolicy.RUNTIME) @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -1234,7 +1261,7 @@ public class ReflectionTest { @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) class A { } */ replaceVal = expectedVals + anno; @@ -1250,17 +1277,17 @@ public class ReflectionTest { BasicContainerRepeatable_Inherited( "@ExpectedBase(value=Foo.class, " + "getAnnotationVal = \"NULL\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\"}, " + "getDeclAnnoVal = \"NULL\", " - + "getAnnosArgs = {\"Foo\", \"Foo\"}, " + + "getAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\"}, " + "getDeclAnnosArgs = {})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = { \"ExpectedBase\", \"ExpectedContainer\"}, " + "getDeclAnnoVal = \"NULL\", " - + "getAnnosArgs = {\"FooContainer\"}, " + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosArgs = {})") { @Override @@ -1280,7 +1307,7 @@ public class ReflectionTest { @Retention(RetentionPolicy.RUNTIME) @Inherited @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -1288,7 +1315,7 @@ public class ReflectionTest { Foo[] value(); } - @FooContainer(value = {@Foo, @Foo}) + @FooContainer(value = {@Foo(1), @Foo(2)}) class SuperClass { } @ExpectedBase @@ -1323,21 +1350,21 @@ public class ReflectionTest { RepeatableAnnoInherited( "@ExpectedBase(value=Foo.class, " + "getAnnotationVal = \"NULL\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\"}, " + // ignores inherited annotations "getDeclAnnoVal = \"NULL\", " + // ignores inherited - "getAnnosArgs = {\"Foo\", \"Foo\"}, " + "getAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\"}, " + "getDeclAnnosArgs = {})", // ignores inherited "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"FooContainer\"}, " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosVals = { \"ExpectedBase\", \"ExpectedContainer\"}, " + // ignores inherited annotations "getDeclAnnoVal = \"NULL\", " + // ignores inherited - "getAnnosArgs = {\"FooContainer\"}, " + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + "getDeclAnnosArgs = {})") { // ignores inherited @Override @@ -1357,7 +1384,7 @@ public class ReflectionTest { @Retention(RetentionPolicy.RUNTIME) @Inherited @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -1365,7 +1392,7 @@ public class ReflectionTest { Foo[] value(); } - @Foo() @Foo() + @Foo(1) @Foo(2) class SuperClass { } @ExpectedBase @@ -1397,25 +1424,27 @@ public class ReflectionTest { return files; } }, + // @ignore 8025924: Several test cases in repeatingAnnotations/combo/ReflectionTest + // fail with ordering issues SingleAnnoWithContainer( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " + + "getAnnotationVal = \"@Foo(value=0)\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," - + "getDeclAnnoVal = \"Foo\"," - + "getAnnosArgs = {\"Foo\", \"Foo\", \"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\", \"Foo\",\"Foo\"})", + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnoVal = \"@Foo(value=0)\"," + + "getAnnosArgs = {\"@Foo(value=0)\", \"@Foo(value=1)\", \"@Foo(value=2)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=0)\", \"@Foo(value=1)\",\"@Foo(value=2)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " - + "getDeclAnnoVal = \"FooContainer\"," - + "getDeclAnnosArgs = {\"FooContainer\"}," - + "getAnnosArgs = {\"FooContainer\"})") { + + "\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=0)\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}, " + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"})") { @Override public Iterable getTestFiles(SrcType srcType, @@ -1449,12 +1478,12 @@ public class ReflectionTest { Sample package-info.java @ExpectedBase @ExpectedContainer - @Foo @FooContainer(value = {@Foo, @Foo}) + @Foo(0) @FooContainer(value = {@Foo(1), @Foo(2)}) package testpkg; @Retention(RetentionPolicy.RUNTIME) @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @interface FooContainer { @@ -1482,7 +1511,7 @@ public class ReflectionTest { @Retention(RetentionPolicy.RUNTIME) @Inherited @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -1492,7 +1521,7 @@ public class ReflectionTest { @ExpectedBase @ExpectedContainer - @Foo @FooContainer(value = {@Foo, @Foo}) + @Foo(0) @FooContainer(value = {@Foo(1), @Foo(2)}) class A { } */ replaceVal = expectedVals + anno; @@ -1508,18 +1537,18 @@ public class ReflectionTest { }, AnnoOnSuperAndSubClass_Inherited( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\" }, " + + "getAnnotationVal = \"@Foo(value=1)\", " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=1)\" }, " + // override every annotation on superClass - "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=1)\"}, " + // ignores inherited annotations - "getDeclAnnoVal = \"Foo\", " // ignores inherited - + "getAnnosArgs = {\"Foo\"}, " - + "getDeclAnnosArgs = { \"Foo\" })", // ignores inherited + "getDeclAnnoVal = \"@Foo(value=1)\", " // ignores inherited + + "getAnnosArgs = {\"@Foo(value=1)\"}, " + + "getDeclAnnosArgs = { \"@Foo(value=1)\" })", // ignores inherited "@ExpectedContainer(value=FooContainer.class, " + "getAnnotationVal = \"NULL\", " - + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\" }, " - + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"Foo\"}, " + + "getAnnotationsVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=1)\" }, " + + "getDeclAnnosVals = {\"ExpectedBase\", \"ExpectedContainer\", \"@Foo(value=1)\"}, " + // ignores inherited annotations "getDeclAnnoVal = \"NULL\", " + // ignores inherited "getAnnosArgs = {}, " + "getDeclAnnosArgs = {})") { @@ -1542,7 +1571,7 @@ public class ReflectionTest { @Retention(RetentionPolicy.RUNTIME) @Inherited @Repeatable(FooContainer.class) - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -1550,12 +1579,12 @@ public class ReflectionTest { Foo[] value(); } - @Foo() + @Foo(0) class SuperClass { } @ExpectedBase @ExpectedContainer - @Foo + @Foo(1) class SubClass extends SuperClass { } */ // @Inherited only works for classes, no switch cases for @@ -1570,7 +1599,7 @@ public class ReflectionTest { .replace("#REPLACE", replaceVal); // Contents for SubClass that extends SuperClass - replaceVal = expectedVals + "\n" + anno; + replaceVal = expectedVals + "\n" + "@Foo(1)"; String subClassContents = SrcType.CLASSEXTENDS.getTemplate() .replace("#CN", className) .replace("#SN", SUPERCLASS) @@ -1623,7 +1652,7 @@ public class ReflectionTest { // @Retention(RetentionPolicy.RUNTIME) // @Inherited // @Repeatable(FooContainer.class) -// @interface Foo {} +// @interface Foo {int value() default Integer.MAX_VALUE;} // @Retention(RetentionPolicy.RUNTIME) // @Inherited @@ -1650,7 +1679,7 @@ public class ReflectionTest { // .replace("#REPLACE", replaceVal); // //Contents for SubClass that extends SuperClass -// anno = Helper.ContentVars.BASEANNO.getVal(); +// anno = "@Foo(0)"; // replaceVal = expectedVals + "\n" + anno; // String subClassContents = SrcType.CLASSEXTENDS.getTemplate() // .replace("#CN", className) @@ -1703,7 +1732,7 @@ public class ReflectionTest { // @Retention(RetentionPolicy.RUNTIME) // @Inherited // @Repeatable(FooContainer.class) -// @interface Foo {} +// @interface Foo {int value() default Integer.MAX_VALUE;} // @Retention(RetentionPolicy.RUNTIME) // @Inherited @@ -1723,7 +1752,7 @@ public class ReflectionTest { // //@Inherited only works for classes, no switch cases for method, field, package // if (srcType == SrcType.CLASS) { // //Contents for SuperClass -// anno = Helper.ContentVars.BASEANNO.getVal(); +// anno = "@Foo(0)"; // replaceVal = commonStmts + "\n" + anno; // String superClassContents = srcType.getTemplate() // .replace("#CN", SUPERCLASS) @@ -1781,7 +1810,7 @@ public class ReflectionTest { // @Retention(RetentionPolicy.RUNTIME) // @Inherited // @Repeatable(FooContainer.class) -// @interface Foo {} +// @interface Foo {int value() default Integer.MAX_VALUE;} // @Retention(RetentionPolicy.RUNTIME) // @Inherited @@ -1808,7 +1837,7 @@ public class ReflectionTest { // .replace("#REPLACE", replaceVal); // //Contents for SubClass that extends SuperClass -// anno = Helper.ContentVars.BASEANNO.getVal(); +// anno = "@Foo(0)"; // replaceVal = expectedVals + "\n" + anno; // String subClassContents = SrcType.CLASSEXTENDS.getTemplate() // .replace("#CN", className) @@ -1859,7 +1888,7 @@ public class ReflectionTest { // @Retention(RetentionPolicy.RUNTIME) // @Inherited // @Repeatable(FooContainer.class) -// @interface Foo {} +// @interface Foo {int value() default Integer.MAX_VALUE;} // @Retention(RetentionPolicy.RUNTIME) // @Inherited @@ -1879,7 +1908,7 @@ public class ReflectionTest { // //@Inherited only works for classes, no switch cases for method, field, package // if (srcType == SrcType.CLASS) { // //Contents for SuperClass -// anno = Helper.ContentVars.BASEANNO.getVal(); +// anno = "@Foo(0)"; // replaceVal = commonStmts + "\n" + anno; // String superClassContents = srcType.getTemplate() // .replace("#CN", SUPERCLASS) @@ -1900,25 +1929,27 @@ public class ReflectionTest { // return files; // } // }, + // @ignore 8025924: Several test cases in repeatingAnnotations/combo/ReflectionTest + // fail with ordering issues SingleOnSuperContainerAndSingleOnSub_Inherited( "@ExpectedBase(value=Foo.class, " - + "getAnnotationVal = \"Foo\", " + + "getAnnotationVal = \"@Foo(value=3)\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," - + "getDeclAnnoVal = \"Foo\"," - + "getAnnosArgs = {\"Foo\", \"Foo\", \"Foo\"}," - + "getDeclAnnosArgs = {\"Foo\", \"Foo\", \"Foo\"})", + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}," + + "getDeclAnnoVal = \"@Foo(value=3)\"," + + "getAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\", \"@Foo(value=3)\"}," + + "getDeclAnnosArgs = {\"@Foo(value=1)\", \"@Foo(value=2)\", \"@Foo(value=3)\"})", "@ExpectedContainer(value=FooContainer.class, " - + "getAnnotationVal = \"FooContainer\", " + + "getAnnotationVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", " + "getAnnotationsVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}, " + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}, " + "getDeclAnnosVals = {" - + "\"ExpectedBase\", \"ExpectedContainer\", \"Foo\", \"FooContainer\"}," - + "getDeclAnnoVal = \"FooContainer\"," - + "getAnnosArgs = {\"FooContainer\"}," - + "getDeclAnnosArgs = {\"FooContainer\"})") { + + "\"ExpectedBase\", \"ExpectedContainer\", \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\", \"@Foo(value=3)\"}," + + "getDeclAnnoVal = \"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"," + + "getAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"}," + + "getDeclAnnosArgs = {\"@FooContainer(value=[@Foo(value=1), @Foo(value=2)])\"})") { @Override public Iterable getTestFiles(SrcType srcType, @@ -1936,7 +1967,7 @@ public class ReflectionTest { Sample testSrc: @Retention(RetentionPolicy.RUNTIME) @Inherited - @interface Foo {} + @interface Foo {int value() default Integer.MAX_VALUE;} @Retention(RetentionPolicy.RUNTIME) @Inherited @@ -1945,12 +1976,12 @@ public class ReflectionTest { Foo[] value(); } - @Foo + @Foo(0) class SuperClass { } @ExpectedBase @ExpectedContainer - @FooContainer(value = {@Foo, @Foo}) @Foo + @FooContainer(value = {@Foo(1), @Foo(2)}) @Foo(3) class SubClass extends SuperClass {} */ @@ -1964,7 +1995,7 @@ public class ReflectionTest { //Contents for SubClass that extends SuperClass anno = Helper.ContentVars.LEGACYCONTAINER.getVal() - + Helper.ContentVars.BASEANNO.getVal(); + + "@Foo(3)"; replaceVal = expectedVals + "\n" + anno; String subClassContents = SrcType.CLASSEXTENDS.getTemplate() .replace("#CN", className) @@ -2015,7 +2046,7 @@ public class ReflectionTest { // @Retention(RetentionPolicy.RUNTIME) // @Inherited // @Repeatable(FooContainer.class) -// @interface Foo {} +// @interface Foo {int value() default Integer.MAX_VALUE;} // @Retention(RetentionPolicy.RUNTIME) // @Inherited @@ -2044,7 +2075,7 @@ public class ReflectionTest { // .replace("#REPLACE", replaceVal); // //Contents for SubClass that extends SuperClass -// anno = Helper.ContentVars.BASEANNO.getVal(); +// anno = "@Foo(0)"; // replaceVal = expectedVals + "\n" + anno; // String subClassContents = SrcType.CLASSEXTENDS.getTemplate() // .replace("#CN", className) @@ -2800,6 +2831,8 @@ public class ReflectionTest { // should be present in actualAnno[]. private static boolean compareAnnotations(Annotation[] actualAnnos, String[] expectedAnnos) { + boolean compOrder = false; + // Length is different if (actualAnnos.length != expectedAnnos.length) { error("Length not same, Actual length = " + actualAnnos.length @@ -2830,12 +2863,16 @@ public class ReflectionTest { // Lengths are same, compare array contents String[] actualArr = new String[actualAnnos.length]; for (Annotation a : actualAnnos) { + if (a.annotationType().getSimpleName().contains("Expected")) actualArr[i++] = a.annotationType().getSimpleName(); + else if (a.annotationType().getName().contains(TESTPKG)) { + String replaced = a.toString().replaceAll(Pattern.quote("testpkg."),""); + actualArr[i++] = replaced; + } else + actualArr[i++] = a.toString(); } - - List actualList = Arrays.asList(actualArr); - List expectedList = Arrays.asList(expectedAnnos); - + List actualList = new ArrayList(Arrays.asList(actualArr)); + List expectedList = new ArrayList(Arrays.asList(expectedAnnos)); if (!actualList.containsAll(expectedList)) { error("Array values are not same"); printArrContents(actualAnnos); @@ -2843,10 +2880,63 @@ public class ReflectionTest { return false; } else { debugPrint("Arr values are same as expected"); + if (CHECKORDERING) { + debugPrint("Checking if annotation ordering is as expected.."); + compOrder = compareOrdering(actualList, expectedList); + if (compOrder) + debugPrint("Arr values ordering is as expected"); + else + error("Arr values ordering is not as expected! actual values: " + + actualList + " expected values: " + expectedList); + } else + compOrder = true; } } + return compOrder; + } + + // Annotation ordering comparison + private static boolean compareOrdering(List actualList, List expectedList) { + boolean order = true; + // Discarding Expected* annotations before comparison of ordering + actualList = iterateList(actualList); + expectedList = iterateList(expectedList); + // Length is different + if (actualList.size() != expectedList.size()) { + error("Length not same, Actual list length = " + actualList.size() + + " Expected list length = " + expectedList.size()); + return false; + } else { + if (actualList.isEmpty() && expectedList.isEmpty()) { return true; } + boolean tmp = true; + for (int i = 0; i < actualList.size(); i++) { + // Checking ordering + if (order) { + if (!actualList.get(i).equals(expectedList.get(i))) { + tmp = false; + debugPrint("Odering is false"); + debugPrint("actualList values: " + actualList + + " expectedList values: " + expectedList); + } + } + } + order = tmp; + } + return order; + } + + private static List iterateList(List list) { + Iterator iter = list.iterator(); + while (iter.hasNext()) { + String anno = iter.next(); + if (anno.contains("Expected")) { + iter.remove(); + } + } + return list; + } private static void printArrContents(Annotation[] actualAnnos) { System.out.print("Actual Arr Values: "); From b49c59f608ba4c0af68e9808331b78274764b660 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Thu, 17 Oct 2013 06:29:58 -0700 Subject: [PATCH 116/152] 8025635: SoftReferences are not cleared before metaspace OOME are thrown Reviewed-by: jcoomes, tamao, tschatzl, stefank --- .../shared/vmGCOperations.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp index 31e6bddf421..6f535034346 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp @@ -211,7 +211,7 @@ void VM_CollectForMetadataAllocation::doit() { // a GC that freed space for the allocation. if (!MetadataAllocationFailALot) { _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); - } + } if (_result == NULL) { if (UseConcMarkSweepGC) { @@ -223,9 +223,7 @@ void VM_CollectForMetadataAllocation::doit() { _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); } if (_result == NULL) { - // Don't clear the soft refs. This GC is for reclaiming metadata - // and is unrelated to the fullness of the Java heap which should - // be the criteria for clearing SoftReferences. + // Don't clear the soft refs yet. if (Verbose && PrintGCDetails && UseConcMarkSweepGC) { gclog_or_tty->print_cr("\nCMS full GC for Metaspace"); } @@ -235,7 +233,7 @@ void VM_CollectForMetadataAllocation::doit() { _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); } - if (_result == NULL && !UseConcMarkSweepGC /* CMS already tried */) { + if (_result == NULL) { // If still failing, allow the Metaspace to expand. // See delta_capacity_until_GC() for explanation of the // amount of the expansion. @@ -243,7 +241,16 @@ void VM_CollectForMetadataAllocation::doit() { // or a MaxMetaspaceSize has been specified on the command line. _result = _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); - + if (_result == NULL) { + // If expansion failed, do a last-ditch collection and try allocating + // again. A last-ditch collection will clear softrefs. This + // behavior is similar to the last-ditch collection done for perm + // gen when it was full and a collection for failed allocation + // did not free perm gen space. + heap->collect_as_vm_thread(GCCause::_last_ditch_collection); + _result = + _loader_data->metaspace_non_null()->allocate(_size, _mdtype); + } } if (Verbose && PrintGCDetails && _result == NULL) { gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size " From 95ddbab8d9a7279216a23290221b0d4c1a0a0526 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 17 Oct 2013 16:15:57 +0200 Subject: [PATCH 117/152] 8019540: licensee reports a JDK8 build failure after 8005849/8005008 fixes integrated Reviewed-by: dholmes, sla --- jdk/makefiles/CopyIntoClasses.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/makefiles/CopyIntoClasses.gmk b/jdk/makefiles/CopyIntoClasses.gmk index 2eb496b2446..ddf5ae8b1e2 100644 --- a/jdk/makefiles/CopyIntoClasses.gmk +++ b/jdk/makefiles/CopyIntoClasses.gmk @@ -91,7 +91,7 @@ ifndef OPENJDK $(SWING_PLAF_WINDOWS_RESOURCES_DIR_CLOSED)/icons/JavaCup32.png endif -ifndef OPENJDK +ifeq ($(ENABLE_JFR), true) JFR_CONFIGURATION_DIR_CLOSED = $(JDK_TOPDIR)/src/closed/share/classes/oracle/jrockit/jfr/settings COPY_FILES += \ $(JFR_CONFIGURATION_DIR_CLOSED)/jfc.xsd From 3d21054d49d8bd63fed45c8b76d120a811b3ecda Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:40:42 -0700 Subject: [PATCH 118/152] Added tag jdk8-b112 for changeset d6efd86ba297 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index a9a38f902cc..8814acccf94 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -233,3 +233,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 91f47e8da5c60de58ed195e9b57f3bf192a18f83 jdk8-b109 4faa09c7fe555de086dd9048d3c5cc92317d6f45 jdk8-b110 d086227bfc45d124f09b3bd72a07956b4073bf71 jdk8-b111 +547316ea137d83d9c63083a9b83db64198fe0c81 jdk8-b112 From 81f227046978a3fa06c9b6f1880fdb0b3d863dd1 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:40:47 -0700 Subject: [PATCH 119/152] Added tag jdk8-b112 for changeset 80c546afbfd1 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 8db624575ae..3b352004341 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -233,3 +233,4 @@ a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108 428428cf5e06163322144cfb5367e1faa86acf20 jdk8-b109 3d2b7ce93c5c2e3db748f29c3d29620a8b3b748a jdk8-b110 85c1c94e723582f9a1dd0251502c42b73d6deea7 jdk8-b111 +43cec76d1d62587a07af07e2d9bec93aba2a506b jdk8-b112 From 101203313073f208f64318a74701cf499cd7c082 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:40:51 -0700 Subject: [PATCH 120/152] Added tag jdk8-b112 for changeset 0bbe54dca484 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 472bde75792..def680895a4 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -385,3 +385,4 @@ c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109 562a3d356de67670b4172b82aca2d30743449e04 hs25-b53 f6962730bbde82f279a0ae3a1c14bc5e58096c6e jdk8-b111 4a845c7a463844cead9e1e1641d6bcfb8a77f1c7 hs25-b54 +0ed9a90f45e1b392c671005f9ee22ce1acf02984 jdk8-b112 From 997f9fca3a66bb3bce269dec3d7fe506ff88fb78 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:40:58 -0700 Subject: [PATCH 121/152] Added tag jdk8-b112 for changeset d0f3600edd98 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index fb2959bf0db..7621bc5f5a1 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -233,3 +233,4 @@ d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 02bfab2aa93899e0f02584f1e85537485a196553 jdk8-b109 4c84c5b447b09aff27f3b72667ab3a5401e85968 jdk8-b110 17ee0d3e97fdb412e48f14d87f504946a708f846 jdk8-b111 +c1f9158fbb9c2da50f6946fffd974e8236e08447 jdk8-b112 From 8fb3f175e0ea193ee1046db0dc6deaf1bf97effc Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:40:59 -0700 Subject: [PATCH 122/152] Added tag jdk8-b112 for changeset 7ac3e6a52e4c --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index a8d225947ad..74b6fb898b4 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -233,3 +233,4 @@ d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108 df5d4d01642572e77fd3c01e4c8703ed3f6eec87 jdk8-b109 cc682329886be2fc26220fc30597ee4e5bba43ed jdk8-b110 32edc7a2c86696dfcbdb6ffae641ff153f8e34bd jdk8-b111 +dbdd5c76250928582cb5342bcf7b299a6007d538 jdk8-b112 From 28cd7f48eebc6480d70b36e74843d8befcc878d7 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:41:12 -0700 Subject: [PATCH 123/152] Added tag jdk8-b112 for changeset 96faa2507e3a --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 8ae4f898e1f..e56bf696bb2 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -233,3 +233,4 @@ fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 985abf1cd327169a317d4ff4f318a8162a5cd47d jdk8-b109 41541097533aa3933a018c8c1c426c1871dfd76e jdk8-b110 af6244ba81b6b8d1bf4ab06587a2067e021e4570 jdk8-b111 +954dd199d6ff3e4cfc42b894c1f611150526eecd jdk8-b112 From c9440bc8fcf8ff4ffcc5d614ba4688522581c450 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 17 Oct 2013 09:41:14 -0700 Subject: [PATCH 124/152] Added tag jdk8-b112 for changeset 49f23f00d4e6 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index b83381913bf..76c92131abf 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -221,3 +221,4 @@ f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 6ec2f9e5ed5bd60c2900976e6a54fdcac2f37e9e jdk8-b109 d49a8c2173f5f90c9a39cc4af8e03cfa8f35ee4c jdk8-b110 75fd3486e584f20475c064a2cd4d01ac6406a511 jdk8-b111 +6a4fdb3bb4e34af4c5bb8db467bb01e13b1a7e31 jdk8-b112 From a45aa286f309892620e309c78e0e64d592c86efe Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Thu, 17 Oct 2013 11:22:39 -0700 Subject: [PATCH 125/152] 8015243: SchemaFactory does not catch enum. value that is not in the value space of the base type, anyURI Reviewed-by: lancea --- jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java index e420f2616b6..a92cd20e399 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java @@ -689,9 +689,13 @@ import java.util.Objects; if (!initializeAuthority(uriSpec.substring(startPos, index))) { index = startPos - 2; } - } - else { + } else if (index < uriSpecLen) { + //Same as java.net.URI: + // DEVIATION: Allow empty authority prior to non-empty + // path, query component or fragment identifier m_host = ""; + } else { + throw new MalformedURIException("Expected authority."); } } From 1285dee32b724122cd84e89c307f18712c08a004 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 17 Oct 2013 13:19:48 -0700 Subject: [PATCH 126/152] 8015912: jdeps support to output in dot file format 8026255: Switch jdeps to follow traditional Java option style Reviewed-by: alanb --- .../classes/com/sun/tools/jdeps/Analyzer.java | 129 +++--- .../classes/com/sun/tools/jdeps/Archive.java | 21 +- .../com/sun/tools/jdeps/ClassFileReader.java | 24 +- .../com/sun/tools/jdeps/JdepsTask.java | 389 ++++++++++++------ .../sun/tools/jdeps/PlatformClassPath.java | 64 +-- .../classes/com/sun/tools/jdeps/Profile.java | 227 ++++++++++ .../classes/com/sun/tools/jdeps/Profiles.java | 241 ----------- .../tools/jdeps/resources/jdeps.properties | 56 ++- langtools/test/tools/jdeps/APIDeps.java | 191 +++++++++ langtools/test/tools/jdeps/Basic.java | 37 +- langtools/test/tools/jdeps/Test.java | 3 + langtools/test/tools/jdeps/b/B.java | 32 ++ langtools/test/tools/jdeps/c/C.java | 27 ++ langtools/test/tools/jdeps/c/I.java | 28 ++ langtools/test/tools/jdeps/d/D.java | 27 ++ langtools/test/tools/jdeps/e/E.java | 28 ++ langtools/test/tools/jdeps/f/F.java | 31 ++ langtools/test/tools/jdeps/g/G.java | 29 ++ langtools/test/tools/jdeps/m/Bar.java | 50 +++ langtools/test/tools/jdeps/m/Foo.java | 33 ++ langtools/test/tools/jdeps/m/Gee.java | 30 ++ 21 files changed, 1176 insertions(+), 521 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/jdeps/Profile.java delete mode 100644 langtools/src/share/classes/com/sun/tools/jdeps/Profiles.java create mode 100644 langtools/test/tools/jdeps/APIDeps.java create mode 100644 langtools/test/tools/jdeps/b/B.java create mode 100644 langtools/test/tools/jdeps/c/C.java create mode 100644 langtools/test/tools/jdeps/c/I.java create mode 100644 langtools/test/tools/jdeps/d/D.java create mode 100644 langtools/test/tools/jdeps/e/E.java create mode 100644 langtools/test/tools/jdeps/f/F.java create mode 100644 langtools/test/tools/jdeps/g/G.java create mode 100644 langtools/test/tools/jdeps/m/Bar.java create mode 100644 langtools/test/tools/jdeps/m/Foo.java create mode 100644 langtools/test/tools/jdeps/m/Gee.java diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java b/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java index ca086e320b0..0dadafb053e 100644 --- a/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java +++ b/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java @@ -25,9 +25,8 @@ package com.sun.tools.jdeps; import com.sun.tools.classfile.Dependency.Location; -import java.util.ArrayList; +import com.sun.tools.jdeps.PlatformClassPath.JDKArchive; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -52,8 +51,8 @@ public class Analyzer { }; private final Type type; - private final List results = new ArrayList(); - private final Map map = new HashMap(); + private final Map results = new HashMap<>(); + private final Map map = new HashMap<>(); private final Archive NOT_FOUND = new Archive(JdepsTask.getMessage("artifact.not.found")); @@ -78,27 +77,27 @@ public class Analyzer { deps = new PackageVisitor(archive); } archive.visit(deps); - results.add(deps); + results.put(archive, deps); } // set the required dependencies - for (ArchiveDeps result: results) { + for (ArchiveDeps result: results.values()) { for (Set set : result.deps.values()) { for (String target : set) { Archive source = getArchive(target); if (result.archive != source) { - if (!result.requiredArchives.contains(source)) { - result.requiredArchives.add(source); + String profile = ""; + if (source instanceof JDKArchive) { + profile = result.profile != null ? result.profile.toString() : ""; + if (result.getTargetProfile(target) == null) { + profile += ", JDK internal API"; + // override the value if it accesses any JDK internal + result.requireArchives.put(source, profile); + continue; + } } - // either a profile name or the archive name - String tname = result.getTargetProfile(target); - if (tname.isEmpty()) { - tname = PlatformClassPath.contains(source) - ? "JDK internal API (" + source.getFileName() + ")" - : source.toString(); - } - if (!result.targetNames.contains(tname)) { - result.targetNames.add(tname); + if (!result.requireArchives.containsKey(source)) { + result.requireArchives.put(source, profile); } } } @@ -106,42 +105,46 @@ public class Analyzer { } } + public boolean hasDependences(Archive archive) { + if (results.containsKey(archive)) { + return results.get(archive).deps.size() > 0; + } + return false; + } + public interface Visitor { + /** + * Visits the source archive to its destination archive of + * a recorded dependency. + */ + void visitArchiveDependence(Archive origin, Archive target, String profile); /** * Visits a recorded dependency from origin to target which can be * a fully-qualified classname, a package name, a profile or * archive name depending on the Analyzer's type. */ - void visit(String origin, String target, String profile); - /** - * Visits the source archive to its destination archive of - * a recorded dependency. - */ - void visit(Archive source, Archive dest); + void visitDependence(String origin, Archive source, String target, Archive archive, String profile); } - public void visitSummary(Visitor v) { - for (ArchiveDeps r : results) { - for (Archive a : r.requiredArchives) { - v.visit(r.archive, a); - } - for (String name : r.targetNames) { - v.visit(r.archive.getFileName(), name, name); - } + public void visitArchiveDependences(Archive source, Visitor v) { + ArchiveDeps r = results.get(source); + for (Map.Entry e : r.requireArchives.entrySet()) { + v.visitArchiveDependence(r.archive, e.getKey(), e.getValue()); } } - public void visit(Visitor v) { - for (ArchiveDeps r: results) { - for (Archive a : r.requiredArchives) { - v.visit(r.archive, a); - } - for (String origin : r.deps.keySet()) { - for (String target : r.deps.get(origin)) { - // filter intra-dependency unless in verbose mode - if (type == Type.VERBOSE || getArchive(origin) != getArchive(target)) { - v.visit(origin, target, r.getTargetProfile(target)); - } + public void visitDependences(Archive source, Visitor v) { + ArchiveDeps r = results.get(source); + for (String origin : r.deps.keySet()) { + for (String target : r.deps.get(origin)) { + Archive archive = getArchive(target); + assert source == getArchive(origin); + Profile profile = r.getTargetProfile(target); + + // filter intra-dependency unless in verbose mode + if (type == Type.VERBOSE || archive != source) { + v.visitDependence(origin, source, target, archive, + profile != null ? profile.toString() : ""); } } } @@ -151,29 +154,15 @@ public class Analyzer { return map.containsKey(name) ? map.get(name) : NOT_FOUND; } - /** - * Returns the file name of the archive for non-JRE class or - * internal JRE classes. It returns empty string for SE API. - */ - public String getArchiveName(String target, String profile) { - Archive source = getArchive(target); - String name = source.getFileName(); - if (PlatformClassPath.contains(source)) - return profile.isEmpty() ? "JDK internal API (" + name + ")" : ""; - return name; - } - private abstract class ArchiveDeps implements Archive.Visitor { final Archive archive; - final Set requiredArchives; - final SortedSet targetNames; + final Map requireArchives; final SortedMap> deps; - + Profile profile = null; ArchiveDeps(Archive archive) { this.archive = archive; - this.requiredArchives = new HashSet(); - this.targetNames = new TreeSet(); - this.deps = new TreeMap>(); + this.requireArchives = new HashMap<>(); + this.deps = new TreeMap<>(); } void add(String loc) { @@ -188,17 +177,19 @@ public class Analyzer { void add(String origin, String target) { SortedSet set = deps.get(origin); if (set == null) { - set = new TreeSet(); - deps.put(origin, set); + deps.put(origin, set = new TreeSet<>()); } if (!set.contains(target)) { set.add(target); + // find the corresponding profile + Profile p = getTargetProfile(target); + if (profile == null || (p != null && profile.profile < p.profile)) { + profile = p; + } } } - public abstract void visit(Location o, Location t); - public abstract String getTargetProfile(String target); - + public abstract Profile getTargetProfile(String target); } private class ClassVisitor extends ArchiveDeps { @@ -211,9 +202,9 @@ public class Analyzer { public void visit(Location o, Location t) { add(o.getClassName(), t.getClassName()); } - public String getTargetProfile(String target) { + public Profile getTargetProfile(String target) { int i = target.lastIndexOf('.'); - return (i > 0) ? Profiles.getProfileName(target.substring(0, i)) : ""; + return (i > 0) ? Profile.getProfile(target.substring(0, i)) : null; } } @@ -231,8 +222,8 @@ public class Analyzer { String pkg = loc.getPackageName(); return pkg.isEmpty() ? "" : pkg; } - public String getTargetProfile(String target) { - return Profiles.getProfileName(target); + public Profile getTargetProfile(String target) { + return Profile.getProfile(target); } } } diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java b/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java index 46cd07e404f..826c7662c92 100644 --- a/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java +++ b/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java @@ -25,7 +25,7 @@ package com.sun.tools.jdeps; import com.sun.tools.classfile.Dependency.Location; -import java.io.File; +import java.nio.file.Path; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -35,21 +35,20 @@ import java.util.Set; * Represents the source of the class files. */ public class Archive { - private final File file; + private final Path path; private final String filename; private final ClassFileReader reader; - private final Map> deps - = new HashMap>(); + private final Map> deps = new HashMap<>(); public Archive(String name) { - this.file = null; + this.path = null; this.filename = name; this.reader = null; } - public Archive(File f, ClassFileReader reader) { - this.file = f; - this.filename = f.getName(); + public Archive(Path p, ClassFileReader reader) { + this.path = p; + this.filename = path.getFileName().toString(); this.reader = reader; } @@ -64,14 +63,14 @@ public class Archive { public void addClass(Location origin) { Set set = deps.get(origin); if (set == null) { - set = new HashSet(); + set = new HashSet<>(); deps.put(origin, set); } } public void addClass(Location origin, Location target) { Set set = deps.get(origin); if (set == null) { - set = new HashSet(); + set = new HashSet<>(); deps.put(origin, set); } set.add(target); @@ -87,7 +86,7 @@ public class Archive { } public String toString() { - return file != null ? file.getPath() : filename; + return path != null ? path.toString() : filename; } interface Visitor { diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java b/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java index 8c947e3d6b1..62219b8f114 100644 --- a/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java +++ b/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java @@ -45,17 +45,17 @@ public class ClassFileReader { /** * Returns a ClassFileReader instance of a given path. */ - public static ClassFileReader newInstance(File path) throws IOException { - if (!path.exists()) { - throw new FileNotFoundException(path.getAbsolutePath()); + public static ClassFileReader newInstance(Path path) throws IOException { + if (!Files.exists(path)) { + throw new FileNotFoundException(path.toString()); } - if (path.isDirectory()) { - return new DirectoryReader(path.toPath()); - } else if (path.getName().endsWith(".jar")) { - return new JarFileReader(path.toPath()); + if (Files.isDirectory(path)) { + return new DirectoryReader(path); + } else if (path.getFileName().toString().endsWith(".jar")) { + return new JarFileReader(path); } else { - return new ClassFileReader(path.toPath()); + return new ClassFileReader(path); } } @@ -163,16 +163,16 @@ public class ClassFileReader { int i = name.lastIndexOf('.'); String pathname = name.replace('.', File.separatorChar) + ".class"; Path p = path.resolve(pathname); - if (!p.toFile().exists()) { + if (!Files.exists(p)) { p = path.resolve(pathname.substring(0, i) + "$" + pathname.substring(i+1, pathname.length())); } - if (p.toFile().exists()) { + if (Files.exists(p)) { return readClassFile(p); } } else { Path p = path.resolve(name + ".class"); - if (p.toFile().exists()) { + if (Files.exists(p)) { return readClassFile(p); } } @@ -193,7 +193,7 @@ public class ClassFileReader { Files.walkFileTree(dir, new SimpleFileVisitor() { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (file.toFile().getName().endsWith(".class")) { + if (file.getFileName().toString().endsWith(".class")) { files.add(file); } return FileVisitResult.CONTINUE; diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java b/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java index c606d963679..66cd5a40530 100644 --- a/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java +++ b/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java @@ -24,12 +24,18 @@ */ package com.sun.tools.jdeps; +import com.sun.tools.classfile.AccessFlags; import com.sun.tools.classfile.ClassFile; import com.sun.tools.classfile.ConstantPoolException; import com.sun.tools.classfile.Dependencies; import com.sun.tools.classfile.Dependencies.ClassFileError; import com.sun.tools.classfile.Dependency; +import com.sun.tools.jdeps.PlatformClassPath.JDKArchive; import java.io.*; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.text.MessageFormat; import java.util.*; import java.util.regex.Pattern; @@ -67,11 +73,10 @@ class JdepsTask { boolean matches(String opt) { for (String a : aliases) { - if (a.equals(opt)) { + if (a.equals(opt)) return true; - } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) { + if (hasArg && opt.startsWith(a + "=")) return true; - } } return false; } @@ -96,62 +101,96 @@ class JdepsTask { } static Option[] recognizedOptions = { - new Option(false, "-h", "-?", "--help") { + new Option(false, "-h", "-?", "-help") { void process(JdepsTask task, String opt, String arg) { task.options.help = true; } }, - new Option(false, "-s", "--summary") { + new Option(true, "-dotoutput") { + void process(JdepsTask task, String opt, String arg) throws BadArgs { + Path p = Paths.get(arg); + if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) { + throw new BadArgs("err.dot.output.path", arg); + } + task.options.dotOutputDir = arg; + } + }, + new Option(false, "-s", "-summary") { void process(JdepsTask task, String opt, String arg) { task.options.showSummary = true; task.options.verbose = Analyzer.Type.SUMMARY; } }, - new Option(false, "-v", "--verbose") { - void process(JdepsTask task, String opt, String arg) { - task.options.verbose = Analyzer.Type.VERBOSE; - } - }, - new Option(true, "-V", "--verbose-level") { + new Option(false, "-v", "-verbose", + "-verbose:package", + "-verbose:class") + { void process(JdepsTask task, String opt, String arg) throws BadArgs { - if ("package".equals(arg)) { - task.options.verbose = Analyzer.Type.PACKAGE; - } else if ("class".equals(arg)) { - task.options.verbose = Analyzer.Type.CLASS; - } else { - throw new BadArgs("err.invalid.arg.for.option", opt); + switch (opt) { + case "-v": + case "-verbose": + task.options.verbose = Analyzer.Type.VERBOSE; + break; + case "-verbose:package": + task.options.verbose = Analyzer.Type.PACKAGE; + break; + case "-verbose:class": + task.options.verbose = Analyzer.Type.CLASS; + break; + default: + throw new BadArgs("err.invalid.arg.for.option", opt); } } }, - new Option(true, "-c", "--classpath") { + new Option(true, "-cp", "-classpath") { void process(JdepsTask task, String opt, String arg) { task.options.classpath = arg; } }, - new Option(true, "-p", "--package") { + new Option(true, "-p", "-package") { void process(JdepsTask task, String opt, String arg) { task.options.packageNames.add(arg); } }, - new Option(true, "-e", "--regex") { + new Option(true, "-e", "-regex") { void process(JdepsTask task, String opt, String arg) { task.options.regex = arg; } }, - new Option(false, "-P", "--profile") { + new Option(true, "-include") { + void process(JdepsTask task, String opt, String arg) throws BadArgs { + task.options.includePattern = Pattern.compile(arg); + } + }, + new Option(false, "-P", "-profile") { void process(JdepsTask task, String opt, String arg) throws BadArgs { task.options.showProfile = true; - if (Profiles.getProfileCount() == 0) { + if (Profile.getProfileCount() == 0) { throw new BadArgs("err.option.unsupported", opt, getMessage("err.profiles.msg")); } } }, - new Option(false, "-R", "--recursive") { + new Option(false, "-apionly") { + void process(JdepsTask task, String opt, String arg) { + task.options.apiOnly = true; + } + }, + new Option(false, "-R", "-recursive") { void process(JdepsTask task, String opt, String arg) { task.options.depth = 0; } }, - new HiddenOption(true, "-d", "--depth") { + new Option(false, "-version") { + void process(JdepsTask task, String opt, String arg) { + task.options.version = true; + } + }, + new HiddenOption(false, "-fullversion") { + void process(JdepsTask task, String opt, String arg) { + task.options.fullVersion = true; + } + }, + new HiddenOption(true, "-depth") { void process(JdepsTask task, String opt, String arg) throws BadArgs { try { task.options.depth = Integer.parseInt(arg); @@ -160,16 +199,6 @@ class JdepsTask { } } }, - new Option(false, "--version") { - void process(JdepsTask task, String opt, String arg) { - task.options.version = true; - } - }, - new HiddenOption(false, "--fullversion") { - void process(JdepsTask task, String opt, String arg) { - task.options.fullVersion = true; - } - }, }; private static final String PROGNAME = "jdeps"; @@ -202,7 +231,7 @@ class JdepsTask { if (options.version || options.fullVersion) { showVersion(options.fullVersion); } - if (classes.isEmpty() && !options.wildcard) { + if (classes.isEmpty() && options.includePattern == null) { if (options.help || options.version || options.fullVersion) { return EXIT_OK; } else { @@ -233,19 +262,51 @@ class JdepsTask { } } - private final List sourceLocations = new ArrayList(); + private final List sourceLocations = new ArrayList<>(); private boolean run() throws IOException { findDependencies(); Analyzer analyzer = new Analyzer(options.verbose); analyzer.run(sourceLocations); - if (options.verbose == Analyzer.Type.SUMMARY) { - printSummary(log, analyzer); + if (options.dotOutputDir != null) { + Path dir = Paths.get(options.dotOutputDir); + Files.createDirectories(dir); + generateDotFiles(dir, analyzer); } else { - printDependencies(log, analyzer); + printRawOutput(log, analyzer); } return true; } + private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException { + Path summary = dir.resolve("summary.dot"); + try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary)); + DotFileFormatter formatter = new DotFileFormatter(sw, "summary")) { + for (Archive archive : sourceLocations) { + analyzer.visitArchiveDependences(archive, formatter); + } + } + if (options.verbose != Analyzer.Type.SUMMARY) { + for (Archive archive : sourceLocations) { + if (analyzer.hasDependences(archive)) { + Path dotfile = dir.resolve(archive.getFileName() + ".dot"); + try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile)); + DotFileFormatter formatter = new DotFileFormatter(pw, archive)) { + analyzer.visitDependences(archive, formatter); + } + } + } + } + } + + private void printRawOutput(PrintWriter writer, Analyzer analyzer) { + for (Archive archive : sourceLocations) { + RawOutputFormatter formatter = new RawOutputFormatter(writer); + analyzer.visitArchiveDependences(archive, formatter); + if (options.verbose != Analyzer.Type.SUMMARY) { + analyzer.visitDependences(archive, formatter); + } + } + } private boolean isValidClassName(String name) { if (!Character.isJavaIdentifierStart(name.charAt(0))) { return false; @@ -259,27 +320,43 @@ class JdepsTask { return true; } - private void findDependencies() throws IOException { - Dependency.Finder finder = Dependencies.getClassDependencyFinder(); - Dependency.Filter filter; - if (options.regex != null) { - filter = Dependencies.getRegexFilter(Pattern.compile(options.regex)); + private Dependency.Filter getDependencyFilter() { + if (options.regex != null) { + return Dependencies.getRegexFilter(Pattern.compile(options.regex)); } else if (options.packageNames.size() > 0) { - filter = Dependencies.getPackageFilter(options.packageNames, false); + return Dependencies.getPackageFilter(options.packageNames, false); } else { - filter = new Dependency.Filter() { + return new Dependency.Filter() { + @Override public boolean accepts(Dependency dependency) { return !dependency.getOrigin().equals(dependency.getTarget()); } }; } + } - List archives = new ArrayList(); - Deque roots = new LinkedList(); + private boolean matches(String classname, AccessFlags flags) { + if (options.apiOnly && !flags.is(AccessFlags.ACC_PUBLIC)) { + return false; + } else if (options.includePattern != null) { + return options.includePattern.matcher(classname.replace('/', '.')).matches(); + } else { + return true; + } + } + + private void findDependencies() throws IOException { + Dependency.Finder finder = + options.apiOnly ? Dependencies.getAPIFinder(AccessFlags.ACC_PROTECTED) + : Dependencies.getClassDependencyFinder(); + Dependency.Filter filter = getDependencyFilter(); + + List archives = new ArrayList<>(); + Deque roots = new LinkedList<>(); for (String s : classes) { - File f = new File(s); - if (f.exists()) { - archives.add(new Archive(f, ClassFileReader.newInstance(f))); + Path p = Paths.get(s); + if (Files.exists(p)) { + archives.add(new Archive(p, ClassFileReader.newInstance(p))); } else { if (isValidClassName(s)) { roots.add(s); @@ -289,9 +366,8 @@ class JdepsTask { } } - List classpaths = new ArrayList(); // for class file lookup - if (options.wildcard) { - // include all archives from classpath to the initial list + List classpaths = new ArrayList<>(); // for class file lookup + if (options.includePattern != null) { archives.addAll(getClassPathArchives(options.classpath)); } else { classpaths.addAll(getClassPathArchives(options.classpath)); @@ -305,8 +381,8 @@ class JdepsTask { // Work queue of names of classfiles to be searched. // Entries will be unique, and for classes that do not yet have // dependencies in the results map. - Deque deque = new LinkedList(); - Set doneClasses = new HashSet(); + Deque deque = new LinkedList<>(); + Set doneClasses = new HashSet<>(); // get the immediate dependencies of the input files for (Archive a : archives) { @@ -318,16 +394,18 @@ class JdepsTask { throw new ClassFileError(e); } - if (!doneClasses.contains(classFileName)) { - doneClasses.add(classFileName); - } - for (Dependency d : finder.findDependencies(cf)) { - if (filter.accepts(d)) { - String cn = d.getTarget().getName(); - if (!doneClasses.contains(cn) && !deque.contains(cn)) { - deque.add(cn); + if (matches(classFileName, cf.access_flags)) { + if (!doneClasses.contains(classFileName)) { + doneClasses.add(classFileName); + } + for (Dependency d : finder.findDependencies(cf)) { + if (filter.accepts(d)) { + String cn = d.getTarget().getName(); + if (!doneClasses.contains(cn) && !deque.contains(cn)) { + deque.add(cn); + } + a.addClass(d.getOrigin(), d.getTarget()); } - a.addClass(d.getOrigin(), d.getTarget()); } } } @@ -379,46 +457,10 @@ class JdepsTask { } } unresolved = deque; - deque = new LinkedList(); + deque = new LinkedList<>(); } while (!unresolved.isEmpty() && depth-- > 0); } - private void printSummary(final PrintWriter out, final Analyzer analyzer) { - Analyzer.Visitor visitor = new Analyzer.Visitor() { - public void visit(String origin, String target, String profile) { - if (options.showProfile) { - out.format("%-30s -> %s%n", origin, target); - } - } - public void visit(Archive origin, Archive target) { - if (!options.showProfile) { - out.format("%-30s -> %s%n", origin, target); - } - } - }; - analyzer.visitSummary(visitor); - } - - private void printDependencies(final PrintWriter out, final Analyzer analyzer) { - Analyzer.Visitor visitor = new Analyzer.Visitor() { - private String pkg = ""; - public void visit(String origin, String target, String profile) { - if (!origin.equals(pkg)) { - pkg = origin; - out.format(" %s (%s)%n", origin, analyzer.getArchive(origin).getFileName()); - } - out.format(" -> %-50s %s%n", target, - (options.showProfile && !profile.isEmpty()) - ? profile - : analyzer.getArchiveName(target, profile)); - } - public void visit(Archive origin, Archive target) { - out.format("%s -> %s%n", origin, target); - } - }; - analyzer.visit(visitor); - } - public void handleOptions(String[] args) throws BadArgs { // process options for (int i=0; i < args.length; i++) { @@ -427,7 +469,7 @@ class JdepsTask { Option option = getOption(name); String param = null; if (option.hasArg) { - if (name.startsWith("--") && name.indexOf('=') > 0) { + if (name.startsWith("-") && name.indexOf('=') > 0) { param = name.substring(name.indexOf('=') + 1, name.length()); } else if (i + 1 < args.length) { param = args[++i]; @@ -447,11 +489,7 @@ class JdepsTask { if (name.charAt(0) == '-') { throw new BadArgs("err.option.after.class", name).showUsage(true); } - if (name.equals("*") || name.equals("\"*\"")) { - options.wildcard = true; - } else { - classes.add(name); - } + classes.add(name); } } } @@ -518,13 +556,15 @@ class JdepsTask { boolean showProfile; boolean showSummary; boolean wildcard; - String regex; + boolean apiOnly; + String dotOutputDir; String classpath = ""; int depth = 1; Analyzer.Type verbose = Analyzer.Type.PACKAGE; - Set packageNames = new HashSet(); + Set packageNames = new HashSet<>(); + String regex; // apply to the dependences + Pattern includePattern; // apply to classes } - private static class ResourceBundleHelper { static final ResourceBundle versionRB; static final ResourceBundle bundle; @@ -547,9 +587,9 @@ class JdepsTask { private List getArchives(List filenames) throws IOException { List result = new ArrayList(); for (String s : filenames) { - File f = new File(s); - if (f.exists()) { - result.add(new Archive(f, ClassFileReader.newInstance(f))); + Path p = Paths.get(s); + if (Files.exists(p)) { + result.add(new Archive(p, ClassFileReader.newInstance(p))); } else { warning("warn.file.not.exist", s); } @@ -558,18 +598,131 @@ class JdepsTask { } private List getClassPathArchives(String paths) throws IOException { - List result = new ArrayList(); + List result = new ArrayList<>(); if (paths.isEmpty()) { return result; } for (String p : paths.split(File.pathSeparator)) { if (p.length() > 0) { - File f = new File(p); - if (f.exists()) { - result.add(new Archive(f, ClassFileReader.newInstance(f))); + List files = new ArrayList<>(); + // wildcard to parse all JAR files e.g. -classpath dir/* + int i = p.lastIndexOf(".*"); + if (i > 0) { + Path dir = Paths.get(p.substring(0, i)); + try (DirectoryStream stream = Files.newDirectoryStream(dir, "*.jar")) { + for (Path entry : stream) { + files.add(entry); + } + } + } else { + files.add(Paths.get(p)); + } + for (Path f : files) { + if (Files.exists(f)) { + result.add(new Archive(f, ClassFileReader.newInstance(f))); + } } } } return result; } + + + /** + * Returns the file name of the archive for non-JRE class or + * internal JRE classes. It returns empty string for SE API. + */ + private static String getArchiveName(Archive source, String profile) { + String name = source.getFileName(); + if (source instanceof JDKArchive) + return profile.isEmpty() ? "JDK internal API (" + name + ")" : ""; + return name; + } + + class RawOutputFormatter implements Analyzer.Visitor { + private final PrintWriter writer; + RawOutputFormatter(PrintWriter writer) { + this.writer = writer; + } + + private String pkg = ""; + @Override + public void visitDependence(String origin, Archive source, + String target, Archive archive, String profile) { + if (!origin.equals(pkg)) { + pkg = origin; + writer.format(" %s (%s)%n", origin, source.getFileName()); + } + String name = (options.showProfile && !profile.isEmpty()) + ? profile + : getArchiveName(archive, profile); + writer.format(" -> %-50s %s%n", target, name); + } + + @Override + public void visitArchiveDependence(Archive origin, Archive target, String profile) { + writer.format("%s -> %s", origin, target); + if (options.showProfile && !profile.isEmpty()) { + writer.format(" (%s)%n", profile); + } else { + writer.format("%n"); + } + } + } + + class DotFileFormatter implements Analyzer.Visitor, AutoCloseable { + private final PrintWriter writer; + private final String name; + DotFileFormatter(PrintWriter writer, String name) { + this.writer = writer; + this.name = name; + writer.format("digraph \"%s\" {%n", name); + } + DotFileFormatter(PrintWriter writer, Archive archive) { + this.writer = writer; + this.name = archive.getFileName(); + writer.format("digraph \"%s\" {%n", name); + writer.format(" // Path: %s%n", archive.toString()); + } + + @Override + public void close() { + writer.println("}"); + } + + private final Set edges = new HashSet<>(); + private String node = ""; + @Override + public void visitDependence(String origin, Archive source, + String target, Archive archive, String profile) { + if (!node.equals(origin)) { + edges.clear(); + node = origin; + } + // if -P option is specified, package name -> profile will + // be shown and filter out multiple same edges. + if (!edges.contains(target)) { + StringBuilder sb = new StringBuilder(); + String name = options.showProfile && !profile.isEmpty() + ? profile + : getArchiveName(archive, profile); + writer.format(" %-50s -> %s;%n", + String.format("\"%s\"", origin), + name.isEmpty() ? String.format("\"%s\"", target) + : String.format("\"%s (%s)\"", target, name)); + edges.add(target); + } + } + + @Override + public void visitArchiveDependence(Archive origin, Archive target, String profile) { + String name = options.showProfile && !profile.isEmpty() + ? profile : ""; + writer.format(" %-30s -> \"%s\";%n", + String.format("\"%s\"", origin.getFileName()), + name.isEmpty() + ? target.getFileName() + : String.format("%s (%s)", target.getFileName(), name)); + } + } } diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java b/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java index 14e25830af9..3c1950a7bb9 100644 --- a/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java +++ b/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java @@ -24,11 +24,11 @@ */ package com.sun.tools.jdeps; -import java.io.File; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; @@ -38,45 +38,38 @@ import java.util.*; */ class PlatformClassPath { private final static List javaHomeArchives = init(); + static List getArchives() { return javaHomeArchives; } - static boolean contains(Archive archive) { - return javaHomeArchives.contains(archive); - } - private static List init() { - List result = new ArrayList(); - String javaHome = System.getProperty("java.home"); - File jre = new File(javaHome, "jre"); - File lib = new File(javaHome, "lib"); - + List result = new ArrayList<>(); + Path home = Paths.get(System.getProperty("java.home")); try { - if (jre.exists() && jre.isDirectory()) { - result.addAll(addJarFiles(new File(jre, "lib"))); - result.addAll(addJarFiles(lib)); - } else if (lib.exists() && lib.isDirectory()) { + if (home.endsWith("jre")) { + // jar files in /jre/lib + result.addAll(addJarFiles(home.resolve("lib"))); + } else if (Files.exists(home.resolve("lib"))) { // either a JRE or a jdk build image - File classes = new File(javaHome, "classes"); - if (classes.exists() && classes.isDirectory()) { + Path classes = home.resolve("classes"); + if (Files.isDirectory(classes)) { // jdk build outputdir - result.add(new Archive(classes, ClassFileReader.newInstance(classes))); + result.add(new JDKArchive(classes, ClassFileReader.newInstance(classes))); } // add other JAR files - result.addAll(addJarFiles(lib)); + result.addAll(addJarFiles(home.resolve("lib"))); } else { - throw new RuntimeException("\"" + javaHome + "\" not a JDK home"); + throw new RuntimeException("\"" + home + "\" not a JDK home"); } + return result; } catch (IOException e) { - throw new RuntimeException(e); + throw new Error(e); } - return result; } - private static List addJarFiles(File f) throws IOException { - final List result = new ArrayList(); - final Path root = f.toPath(); + private static List addJarFiles(final Path root) throws IOException { + final List result = new ArrayList<>(); final Path ext = root.resolve("ext"); Files.walkFileTree(root, new SimpleFileVisitor() { @Override @@ -91,17 +84,30 @@ class PlatformClassPath { } } @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + public FileVisitResult visitFile(Path p, BasicFileAttributes attrs) throws IOException { - File f = file.toFile(); - String fn = f.getName(); - if (fn.endsWith(".jar") && !fn.equals("alt-rt.jar")) { - result.add(new Archive(f, ClassFileReader.newInstance(f))); + String fn = p.getFileName().toString(); + if (fn.endsWith(".jar")) { + // JDK may cobundle with JavaFX that doesn't belong to any profile + // Treat jfxrt.jar as regular Archive + result.add(fn.equals("jfxrt.jar") + ? new Archive(p, ClassFileReader.newInstance(p)) + : new JDKArchive(p, ClassFileReader.newInstance(p))); } return FileVisitResult.CONTINUE; } }); return result; } + + /** + * A JDK archive is part of the JDK containing the Java SE API + * or implementation classes (i.e. JDK internal API) + */ + static class JDKArchive extends Archive { + JDKArchive(Path p, ClassFileReader reader) { + super(p, reader); + } + } } diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/Profile.java b/langtools/src/share/classes/com/sun/tools/jdeps/Profile.java new file mode 100644 index 00000000000..47af4b2041f --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/jdeps/Profile.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.jdeps; + +import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.Annotation.*; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.RuntimeAnnotations_attribute; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.jar.JarFile; + +/** + * Build the profile information from ct.sym if exists. + */ +enum Profile { + + COMPACT1("compact1", 1), + COMPACT2("compact2", 2), + COMPACT3("compact3", 3), + FULL_JRE("Full JRE", 4); + + final String name; + final int profile; + final Set packages; + final Set proprietaryPkgs; + + Profile(String name, int profile) { + this.name = name; + this.profile = profile; + this.packages = new HashSet<>(); + this.proprietaryPkgs = new HashSet<>(); + } + + @Override + public String toString() { + return name; + } + + public static int getProfileCount() { + return PackageToProfile.map.values().size(); + } + + /** + * Returns the Profile for the given package name. It returns an empty + * string if the given package is not in any profile. + */ + public static Profile getProfile(String pn) { + Profile profile = PackageToProfile.map.get(pn); + return (profile != null && profile.packages.contains(pn)) + ? profile : null; + } + + static class PackageToProfile { + static Map map = initProfiles(); + + private static Map initProfiles() { + try { + String profilesProps = System.getProperty("jdeps.profiles"); + if (profilesProps != null) { + // for testing for JDK development build where ct.sym doesn't exist + initProfilesFromProperties(profilesProps); + } else { + Path home = Paths.get(System.getProperty("java.home")); + if (home.endsWith("jre")) { + home = home.getParent(); + } + Path ctsym = home.resolve("lib").resolve("ct.sym"); + if (Files.exists(ctsym)) { + // parse ct.sym and load information about profiles + try (JarFile jf = new JarFile(ctsym.toFile())) { + ClassFileReader reader = ClassFileReader.newInstance(ctsym, jf); + for (ClassFile cf : reader.getClassFiles()) { + findProfile(cf); + } + } + } + } + } catch (IOException | ConstantPoolException e) { + throw new Error(e); + } + HashMap map = new HashMap<>(); + for (Profile profile : Profile.values()) { + for (String pn : profile.packages) { + if (!map.containsKey(pn)) { + // split packages in the JRE: use the smaller compact + map.put(pn, profile); + } + } + for (String pn : profile.proprietaryPkgs) { + if (!map.containsKey(pn)) { + map.put(pn, profile); + } + } + } + return map; + } + private static final String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;"; + private static final String PROPRIETARY_ANNOTATION = "Lsun/Proprietary+Annotation;"; + private static Profile findProfile(ClassFile cf) throws ConstantPoolException { + RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute) + cf.attributes.get(Attribute.RuntimeInvisibleAnnotations); + int index = 0; + boolean proprietary = false; + if (attr != null) { + for (int i = 0; i < attr.annotations.length; i++) { + Annotation ann = attr.annotations[i]; + String annType = cf.constant_pool.getUTF8Value(ann.type_index); + if (PROFILE_ANNOTATION.equals(annType)) { + for (int j = 0; j < ann.num_element_value_pairs; j++) { + Annotation.element_value_pair pair = ann.element_value_pairs[j]; + Primitive_element_value ev = (Primitive_element_value) pair.value; + CONSTANT_Integer_info info = (CONSTANT_Integer_info) + cf.constant_pool.get(ev.const_value_index); + index = info.value; + break; + } + } else if (PROPRIETARY_ANNOTATION.equals(annType)) { + proprietary = true; + } + } + } + + Profile p = null; // default + switch (index) { + case 1: + p = Profile.COMPACT1; break; + case 2: + p = Profile.COMPACT2; break; + case 3: + p = Profile.COMPACT3; break; + case 4: + p = Profile.FULL_JRE; break; + default: + // skip classes with profile=0 + // Inner classes are not annotated with the profile annotation + return null; + } + + String name = cf.getName(); + int i = name.lastIndexOf('/'); + name = (i > 0) ? name.substring(0, i).replace('/', '.') : ""; + if (proprietary) { + p.proprietaryPkgs.add(name); + } else { + p.packages.add(name); + } + return p; + } + + private static void initProfilesFromProperties(String path) throws IOException { + Properties props = new Properties(); + try (FileReader reader = new FileReader(path)) { + props.load(reader); + } + for (Profile prof : Profile.values()) { + int i = prof.profile; + String key = props.getProperty("profile." + i + ".name"); + if (key == null) { + throw new RuntimeException(key + " missing in " + path); + } + String n = props.getProperty("profile." + i + ".packages"); + String[] pkgs = n.split("\\s+"); + for (String p : pkgs) { + if (p.isEmpty()) continue; + prof.packages.add(p); + } + } + } + } + + // for debugging + public static void main(String[] args) { + if (args.length == 0) { + if (Profile.getProfileCount() == 0) { + System.err.println("No profile is present in this JDK"); + } + for (Profile p : Profile.values()) { + String profileName = p.name; + SortedSet set = new TreeSet<>(p.packages); + for (String s : set) { + // filter out the inner classes that are not annotated with + // the profile annotation + if (PackageToProfile.map.get(s) == p) { + System.out.format("%2d: %-10s %s%n", p.profile, profileName, s); + profileName = ""; + } else { + System.err.format("Split package: %s in %s and %s %n", + s, PackageToProfile.map.get(s).name, p.name); + } + } + } + } + for (String pn : args) { + System.out.format("%s in %s%n", pn, getProfile(pn)); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/Profiles.java b/langtools/src/share/classes/com/sun/tools/jdeps/Profiles.java deleted file mode 100644 index 0c7b4ccd027..00000000000 --- a/langtools/src/share/classes/com/sun/tools/jdeps/Profiles.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.sun.tools.jdeps; - -import com.sun.tools.classfile.Annotation; -import com.sun.tools.classfile.Annotation.*; -import com.sun.tools.classfile.Attribute; -import com.sun.tools.classfile.ClassFile; -import com.sun.tools.classfile.ConstantPool; -import com.sun.tools.classfile.ConstantPool.*; -import com.sun.tools.classfile.ConstantPoolException; -import com.sun.tools.classfile.RuntimeAnnotations_attribute; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.jar.JarFile; - -/** - * Build the profile information from ct.sym if exists. - */ -class Profiles { - private static final Map map = initProfiles(); - /** - * Returns the name of the profile for the given package name. - * It returns an empty string if the given package is not in any profile. - */ - public static String getProfileName(String pn) { - Profile profile = map.get(pn); - return (profile != null && profile.packages.contains(pn)) - ? profile.name : ""; - } - - public static int getProfileCount() { - return new HashSet(map.values()).size(); - } - - private static Map initProfiles() { - List profiles = new ArrayList(); - try { - String profilesProps = System.getProperty("jdeps.profiles"); - if (profilesProps != null) { - // for testing for JDK development build where ct.sym doesn't exist - initProfilesFromProperties(profiles, profilesProps); - } else { - Path home = Paths.get(System.getProperty("java.home")); - if (home.endsWith("jre")) { - home = home.getParent(); - } - Path ctsym = home.resolve("lib").resolve("ct.sym"); - if (ctsym.toFile().exists()) { - // add a default Full JRE - profiles.add(0, new Profile("Full JRE", 0)); - // parse ct.sym and load information about profiles - try (JarFile jf = new JarFile(ctsym.toFile())) { - ClassFileReader reader = ClassFileReader.newInstance(ctsym, jf); - for (ClassFile cf : reader.getClassFiles()) { - findProfile(profiles, cf); - } - } - - // merge the last Profile with the "Full JRE" - if (profiles.size() > 1) { - Profile fullJRE = profiles.get(0); - Profile p = profiles.remove(profiles.size() - 1); - for (String pn : fullJRE.packages) { - // The last profile contains the packages determined from ct.sym. - // Move classes annotated profile==0 or no attribute that are - // added in the fullJRE profile to either supported or proprietary - // packages appropriately - if (p.proprietaryPkgs.contains(pn)) { - p.proprietaryPkgs.add(pn); - } else { - p.packages.add(pn); - } - } - fullJRE.packages.clear(); - fullJRE.proprietaryPkgs.clear(); - fullJRE.packages.addAll(p.packages); - fullJRE.proprietaryPkgs.addAll(p.proprietaryPkgs); - } - } - } - } catch (IOException | ConstantPoolException e) { - throw new Error(e); - } - HashMap map = new HashMap(); - for (Profile profile : profiles) { - // Inner classes are not annotated with the profile annotation - // packages may be in one profile but also appear in the Full JRE - // Full JRE is always the first element in profiles list and - // so the map will contain the appropriate Profile - for (String pn : profile.packages) { - map.put(pn, profile); - } - for (String pn : profile.proprietaryPkgs) { - map.put(pn, profile); - } - } - return map; - } - - private static final String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;"; - private static final String PROPRIETARY_ANNOTATION = "Lsun/Proprietary+Annotation;"; - private static Profile findProfile(List profiles, ClassFile cf) - throws ConstantPoolException - { - RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute) - cf.attributes.get(Attribute.RuntimeInvisibleAnnotations); - int index = 0; - boolean proprietary = false; - if (attr != null) { - for (int i = 0; i < attr.annotations.length; i++) { - Annotation ann = attr.annotations[i]; - String annType = cf.constant_pool.getUTF8Value(ann.type_index); - if (PROFILE_ANNOTATION.equals(annType)) { - for (int j = 0; j < ann.num_element_value_pairs; j++) { - Annotation.element_value_pair pair = ann.element_value_pairs[j]; - Primitive_element_value ev = (Primitive_element_value)pair.value; - CONSTANT_Integer_info info = (CONSTANT_Integer_info) - cf.constant_pool.get(ev.const_value_index); - index = info.value; - break; - } - } else if (PROPRIETARY_ANNOTATION.equals(annType)) { - proprietary = true; - } - } - if (index >= profiles.size()) { - Profile p = null; - for (int i = profiles.size(); i <= index; i++) { - p = new Profile(i); - profiles.add(p); - } - } - } - - Profile p = profiles.get(index); - String name = cf.getName(); - int i = name.lastIndexOf('/'); - name = (i > 0) ? name.substring(0, i).replace('/','.') : ""; - if (proprietary) { - p.proprietaryPkgs.add(name); - } else { - p.packages.add(name); - } - return p; - } - - private static void initProfilesFromProperties(List profiles, String path) - throws IOException - { - Properties props = new Properties(); - try (FileReader reader = new FileReader(path)) { - props.load(reader); - } - int i=1; - String key; - while (props.containsKey((key = "profile." + i + ".name"))) { - Profile profile = new Profile(props.getProperty(key), i); - profiles.add(profile); - String n = props.getProperty("profile." + i + ".packages"); - String[] pkgs = n.split("\\s+"); - for (String p : pkgs) { - if (p.isEmpty()) continue; - profile.packages.add(p); - } - i++; - } - } - - private static class Profile { - final String name; - final int profile; - final Set packages; - final Set proprietaryPkgs; - Profile(int profile) { - this("compact" + profile, profile); - } - Profile(String name, int profile) { - this.name = name; - this.profile = profile; - this.packages = new HashSet(); - this.proprietaryPkgs = new HashSet(); - } - public String toString() { - return name; - } - } - - // for debugging - public static void main(String[] args) { - if (args.length == 0) { - Profile[] profiles = new Profile[getProfileCount()]; - for (Profile p : map.values()) { - // move the zeroth profile to the last - int index = p.profile == 0 ? profiles.length-1 : p.profile-1; - profiles[index] = p; - } - for (Profile p : profiles) { - String profileName = p.name; - SortedSet set = new TreeSet(p.packages); - for (String s : set) { - // filter out the inner classes that are not annotated with - // the profile annotation - if (map.get(s) == p) { - System.out.format("%-10s %s%n", profileName, s); - profileName = ""; - } - } - } - } - for (String pn : args) { - System.out.format("%s in %s%n", pn, getProfileName(pn)); - } - } -} diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties index 7a01d8f2610..4b86bd6da2b 100644 --- a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties +++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties @@ -5,46 +5,63 @@ use -h, -? or --help for a list of possible options main.usage=\ Usage: {0} \n\ where can be a pathname to a .class file, a directory, a JAR file,\n\ -or a fully-qualified classname or wildcard "*". Possible options include: +or a fully-qualified class name. Possible options include: error.prefix=Error: warn.prefix=Warning: main.opt.h=\ -\ -h -? --help Print this usage message +\ -h -? -help Print this usage message main.opt.version=\ -\ --version Version information - -main.opt.V=\ -\ -V --verbose-level= Print package-level or class-level dependencies\n\ -\ Valid levels are: "package" and "class" +\ -version Version information main.opt.v=\ -\ -v --verbose Print additional information +\ -v -verbose Print all class level dependencies\n\ +\ -verbose:package Print package-level dependencies excluding\n\ +\ dependencies within the same archive\n\ +\ -verbose:class Print class-level dependencies excluding\n\ +\ dependencies within the same archive main.opt.s=\ -\ -s --summary Print dependency summary only +\ -s -summary Print dependency summary only main.opt.p=\ -\ -p --package= Restrict analysis to classes in this package\n\ -\ (may be given multiple times) +\ -p -package Finds dependences in the given package\n\ +\ (may be given multiple times) main.opt.e=\ -\ -e --regex= Restrict analysis to packages matching pattern\n\ -\ (-p and -e are exclusive) +\ -e -regex Finds dependences in packages matching pattern\n\ +\ (-p and -e are exclusive) + +main.opt.include=\ +\ -include Restrict analysis to classes matching pattern\n\ +\ This option filters the list of classes to\n\ +\ be analyzed. It can be used together with\n\ +\ -p and -e which apply pattern to the dependences main.opt.P=\ -\ -P --profile Show profile or the file containing a package +\ -P -profile Show profile or the file containing a package -main.opt.c=\ -\ -c --classpath= Specify where to find class files +main.opt.cp=\ +\ -cp -classpath Specify where to find class files main.opt.R=\ -\ -R --recursive Recursively traverse all dependencies +\ -R -recursive Recursively traverse all dependencies -main.opt.d=\ -\ -d --depth= Specify the depth of the transitive dependency analysis +main.opt.apionly=\ +\ -apionly Restrict analysis to APIs i.e. dependences\n\ +\ from the signature of public and protected\n\ +\ members of public classes including field\n\ +\ type, method parameter types, returned type,\n\ +\ checked exception types etc + +main.opt.dotoutput=\ +\ -dotoutput Destination directory for DOT file output + +main.opt.depth=\ +\ -depth= Specify the depth of the transitive\n\ +\ dependency analysis err.unknown.option=unknown option: {0} err.missing.arg=no value given for {0} @@ -53,6 +70,7 @@ err.invalid.arg.for.option=invalid argument for option: {0} err.option.after.class=option must be specified before classes: {0} err.option.unsupported={0} not supported: {1} err.profiles.msg=No profile information +err.dot.output.path=invalid path: {0} warn.invalid.arg=Invalid classname or pathname not exist: {0} warn.split.package=package {0} defined in {1} {2} diff --git a/langtools/test/tools/jdeps/APIDeps.java b/langtools/test/tools/jdeps/APIDeps.java new file mode 100644 index 00000000000..530e1d37b7c --- /dev/null +++ b/langtools/test/tools/jdeps/APIDeps.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8015912 + * @summary find API dependencies + * @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G + * @run main APIDeps + */ + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.*; + +public class APIDeps { + private static boolean symbolFileExist = initProfiles(); + private static boolean initProfiles() { + // check if ct.sym exists; if not use the profiles.properties file + Path home = Paths.get(System.getProperty("java.home")); + if (home.endsWith("jre")) { + home = home.getParent(); + } + Path ctsym = home.resolve("lib").resolve("ct.sym"); + boolean symbolExists = ctsym.toFile().exists(); + if (!symbolExists) { + Path testSrcProfiles = + Paths.get(System.getProperty("test.src", "."), "profiles.properties"); + if (!testSrcProfiles.toFile().exists()) + throw new Error(testSrcProfiles + " does not exist"); + System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n", + ctsym, testSrcProfiles); + System.setProperty("jdeps.profiles", testSrcProfiles.toString()); + } + return symbolExists; + } + + public static void main(String... args) throws Exception { + int errors = 0; + errors += new APIDeps().run(); + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + int run() throws IOException { + File testDir = new File(System.getProperty("test.classes", ".")); + String testDirBasename = testDir.toPath().getFileName().toString(); + File mDir = new File(testDir, "m"); + // all dependencies + test(new File(mDir, "Bar.class"), + new String[] {"java.lang.Object", "java.lang.String", + "java.util.Set", "java.util.HashSet", + "java.lang.management.ManagementFactory", + "java.lang.management.RuntimeMXBean", + "b.B", "c.C", "d.D", "f.F", "g.G"}, + new String[] {"compact1", "compact3", testDirBasename}, + new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"}); + test(new File(mDir, "Foo.class"), + new String[] {"c.I", "e.E", "f.F", "m.Bar"}, + new String[] {testDirBasename}, + new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"}); + test(new File(mDir, "Gee.class"), + new String[] {"g.G", "sun.misc.Lock"}, + new String[] {testDirBasename, "JDK internal API"}, + new String[] {"-classpath", testDir.getPath(), "-verbose"}); + // parse only APIs + test(mDir, + new String[] {"java.lang.Object", "java.lang.String", + "java.util.Set", + "c.C", "d.D", "c.I", "e.E", "m.Bar"}, + new String[] {"compact1", testDirBasename, mDir.getName()}, + new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "-apionly"}); + return errors; + } + + void test(File file, String[] expect, String[] profiles) { + test(file, expect, profiles, new String[0]); + } + + void test(File file, String[] expect, String[] profiles, String[] options) { + List args = new ArrayList<>(Arrays.asList(options)); + if (file != null) { + args.add(file.getPath()); + } + checkResult("api-dependencies", expect, profiles, + jdeps(args.toArray(new String[0]))); + } + + Map jdeps(String... args) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + System.err.println("jdeps " + Arrays.toString(args)); + int rc = com.sun.tools.jdeps.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + if (!out.isEmpty()) + System.err.println(out); + if (rc != 0) + throw new Error("jdeps failed: rc=" + rc); + return findDeps(out); + } + + // Pattern used to parse lines + private static Pattern linePattern = Pattern.compile(".*\r?\n"); + private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)"); + + // Use the linePattern to break the given String into lines, applying + // the pattern to each line to see if we have a match + private static Map findDeps(String out) { + Map result = new HashMap<>(); + Matcher lm = linePattern.matcher(out); // Line matcher + Matcher pm = null; // Pattern matcher + int lines = 0; + while (lm.find()) { + lines++; + CharSequence cs = lm.group(); // The current line + if (pm == null) + pm = pattern.matcher(cs); + else + pm.reset(cs); + if (pm.find()) + result.put(pm.group(1), pm.group(2).trim()); + if (lm.end() == out.length()) + break; + } + return result; + } + + void checkResult(String label, String[] expect, Collection found) { + List list = Arrays.asList(expect); + if (!isEqual(list, found)) + error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'"); + } + + void checkResult(String label, String[] expect, String[] profiles, Map result) { + // check the dependencies + checkResult(label, expect, result.keySet()); + // check profile information + Set values = new TreeSet<>(); + String internal = "JDK internal API"; + for (String s: result.values()) { + if (s.startsWith(internal)){ + values.add(internal); + } else { + values.add(s); + } + } + checkResult(label, profiles, values); + } + + boolean isEqual(List expected, Collection found) { + if (expected.size() != found.size()) + return false; + + List list = new ArrayList<>(found); + list.removeAll(expected); + return list.isEmpty(); + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff --git a/langtools/test/tools/jdeps/Basic.java b/langtools/test/tools/jdeps/Basic.java index e68875b5eae..fd5242aaa55 100644 --- a/langtools/test/tools/jdeps/Basic.java +++ b/langtools/test/tools/jdeps/Basic.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8003562 8005428 + * @bug 8003562 8005428 8015912 * @summary Basic tests for jdeps tool * @build Test p.Foo * @run main Basic @@ -79,40 +79,33 @@ public class Basic { new String[] {"compact1", "compact1", "compact3"}); // test class-level dependency output test(new File(testDir, "Test.class"), - new String[] {"java.lang.Object", "p.Foo"}, - new String[] {"compact1", "not found"}, - new String[] {"-V", "class"}); + new String[] {"java.lang.Object", "java.lang.String", "p.Foo"}, + new String[] {"compact1", "compact1", "not found"}, + new String[] {"-verbose:class"}); // test -p option test(new File(testDir, "Test.class"), new String[] {"p.Foo"}, new String[] {"not found"}, - new String[] {"--verbose-level=class", "-p", "p"}); + new String[] {"-verbose:class", "-p", "p"}); // test -e option test(new File(testDir, "Test.class"), new String[] {"p.Foo"}, new String[] {"not found"}, - new String[] {"-V", "class", "-e", "p\\..*"}); + new String[] {"-verbose:class", "-e", "p\\..*"}); test(new File(testDir, "Test.class"), new String[] {"java.lang"}, new String[] {"compact1"}, - new String[] {"-V", "package", "-e", "java\\.lang\\..*"}); - // test -classpath and wildcard options + new String[] {"-verbose:package", "-e", "java\\.lang\\..*"}); + // test -classpath and -include options test(null, - new String[] {"com.sun.tools.jdeps", "java.lang", "java.util", - "java.util.regex", "java.io", "java.nio.file", + new String[] {"java.lang", "java.util", "java.lang.management"}, - new String[] {(symbolFileExist? "not found" : "JDK internal API (classes)"), - "compact1", "compact1", "compact1", - "compact1", "compact1", "compact3"}, - new String[] {"--classpath", testDir.getPath(), "*"}); - /* Temporary disable this test case. Test.class has a dependency - * on java.lang.String on certain windows machine (8008479). - // -v shows intra-dependency - test(new File(testDir, "Test.class"), - new String[] {"java.lang.Object", "p.Foo"}, - new String[] {"compact1", testDir.getName()}, - new String[] {"-v", "--classpath", testDir.getPath(), "Test.class"}); - */ + new String[] {"compact1", "compact1", "compact3"}, + new String[] {"-classpath", testDir.getPath(), "-include", "p.+|Test.class"}); + test(new File(testDir, "Test.class"), + new String[] {"java.lang.Object", "java.lang.String", "p.Foo"}, + new String[] {"compact1", "compact1", testDir.getName()}, + new String[] {"-v", "-classpath", testDir.getPath(), "Test.class"}); return errors; } diff --git a/langtools/test/tools/jdeps/Test.java b/langtools/test/tools/jdeps/Test.java index 8adc7b4f630..1a7a96a69ae 100644 --- a/langtools/test/tools/jdeps/Test.java +++ b/langtools/test/tools/jdeps/Test.java @@ -25,4 +25,7 @@ public class Test { public void test() { p.Foo f = new p.Foo(); } + private String name() { + return "this test"; + } } diff --git a/langtools/test/tools/jdeps/b/B.java b/langtools/test/tools/jdeps/b/B.java new file mode 100644 index 00000000000..e3f2af89385 --- /dev/null +++ b/langtools/test/tools/jdeps/b/B.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package b; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({TYPE, METHOD, FIELD}) +public @interface B { +} diff --git a/langtools/test/tools/jdeps/c/C.java b/langtools/test/tools/jdeps/c/C.java new file mode 100644 index 00000000000..60d85ff7202 --- /dev/null +++ b/langtools/test/tools/jdeps/c/C.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package c; + +public class C { +} diff --git a/langtools/test/tools/jdeps/c/I.java b/langtools/test/tools/jdeps/c/I.java new file mode 100644 index 00000000000..12af75a46af --- /dev/null +++ b/langtools/test/tools/jdeps/c/I.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package c; + +public interface I { + void run(); +} diff --git a/langtools/test/tools/jdeps/d/D.java b/langtools/test/tools/jdeps/d/D.java new file mode 100644 index 00000000000..96b183cb108 --- /dev/null +++ b/langtools/test/tools/jdeps/d/D.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package d; + +public class D { +} diff --git a/langtools/test/tools/jdeps/e/E.java b/langtools/test/tools/jdeps/e/E.java new file mode 100644 index 00000000000..bab738be986 --- /dev/null +++ b/langtools/test/tools/jdeps/e/E.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package e; + +// use compact2 +public class E extends java.rmi.RemoteException { +} diff --git a/langtools/test/tools/jdeps/f/F.java b/langtools/test/tools/jdeps/f/F.java new file mode 100644 index 00000000000..dc43c9ccd73 --- /dev/null +++ b/langtools/test/tools/jdeps/f/F.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package f; + +public class F { + public F() { + // jdk internal API + sun.misc.Unsafe.getUnsafe(); + } +} diff --git a/langtools/test/tools/jdeps/g/G.java b/langtools/test/tools/jdeps/g/G.java new file mode 100644 index 00000000000..c3f9fd6e805 --- /dev/null +++ b/langtools/test/tools/jdeps/g/G.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package g; + +public class G { + // Full JRE + private static final boolean gui = java.beans.Beans.isGuiAvailable(); +} diff --git a/langtools/test/tools/jdeps/m/Bar.java b/langtools/test/tools/jdeps/m/Bar.java new file mode 100644 index 00000000000..3988274ab24 --- /dev/null +++ b/langtools/test/tools/jdeps/m/Bar.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package m; + +import java.util.*; + +@b.B +public class Bar { + public final Set set = new HashSet<>(); + protected d.D d; + private f.F f; + + public Bar() { + // compact3 + java.lang.management.ManagementFactory.getRuntimeMXBean(); + } + + protected c.C c() { + return new c.C(); + } + + /* package private */ void setF(f.F o) { + f = o; + } + + private g.G g() { + return new g.G(); + } +} diff --git a/langtools/test/tools/jdeps/m/Foo.java b/langtools/test/tools/jdeps/m/Foo.java new file mode 100644 index 00000000000..67b7578ee29 --- /dev/null +++ b/langtools/test/tools/jdeps/m/Foo.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package m; + +public class Foo extends Bar implements c.I { + public void foo() throws e.E { + } + public void run() { + setF(new f.F()); + } +} + diff --git a/langtools/test/tools/jdeps/m/Gee.java b/langtools/test/tools/jdeps/m/Gee.java new file mode 100644 index 00000000000..749847e72a0 --- /dev/null +++ b/langtools/test/tools/jdeps/m/Gee.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package m; + + +class Gee extends g.G { + public sun.misc.Lock lock; +} + From 4f5a89a5469fe382bff4b7ec3ff4e198b27c5926 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Thu, 17 Oct 2013 14:07:57 -0700 Subject: [PATCH 127/152] 8026062: webrev.ksh: fix bug title web scraping, remove teamware, sac, "open bug", -l and wxfile support Reviewed-by: weijun, dsamersoff, darcy, jrose, tbell --- make/scripts/webrev.ksh | 586 +++++----------------------------------- 1 file changed, 64 insertions(+), 522 deletions(-) diff --git a/make/scripts/webrev.ksh b/make/scripts/webrev.ksh index d36e62b27a1..9571697f13f 100644 --- a/make/scripts/webrev.ksh +++ b/make/scripts/webrev.ksh @@ -27,7 +27,7 @@ # Documentation is available via 'webrev -h'. # -WEBREV_UPDATED=24.1-hg+openjdk.java.net +WEBREV_UPDATED=25.0-hg+openjdk.java.net HTML=' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> \n' -STDHEAD=' +STDHEAD=' +